{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://json.schemastore.org/claude-code-plugin-manifest.json",
  "$comment": "Generated on 2026-04-23T05:09:41.810Z",
  "type": "object",
  "properties": {
    "$schema": {
      "description": "JSON Schema reference for editor autocomplete/validation; ignored at load time",
      "type": "string"
    },
    "name": {
      "description": "Unique identifier for the plugin, used for namespacing (prefer kebab-case)",
      "type": "string",
      "minLength": 1
    },
    "version": {
      "description": "Semantic version (e.g., 1.2.3) following semver.org specification",
      "type": "string"
    },
    "description": {
      "description": "Brief, user-facing explanation of what the plugin provides",
      "type": "string"
    },
    "author": {
      "description": "Information about the plugin creator or maintainer",
      "type": "object",
      "properties": {
        "name": {
          "description": "Display name of the plugin author or organization",
          "type": "string",
          "minLength": 1
        },
        "email": {
          "description": "Contact email for support or feedback",
          "type": "string"
        },
        "url": {
          "description": "Website, GitHub profile, or organization URL",
          "type": "string"
        }
      },
      "required": ["name"]
    },
    "homepage": {
      "description": "Plugin homepage or documentation URL",
      "type": "string",
      "format": "uri"
    },
    "repository": {
      "description": "Source code repository URL",
      "type": "string"
    },
    "license": {
      "description": "SPDX license identifier (e.g., MIT, Apache-2.0)",
      "type": "string"
    },
    "keywords": {
      "description": "Tags for plugin discovery and categorization",
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "dependencies": {
      "description": "Plugins that must be enabled for this plugin to function. Bare names (no \"@marketplace\") are resolved against the declaring plugin's own marketplace.",
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "string",
            "pattern": "^[A-Za-z0-9][-A-Za-z0-9._]*(@[A-Za-z0-9][-A-Za-z0-9._]*)?(@\\^[^@]*)?$"
          },
          {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "pattern": "^[A-Za-z0-9][-A-Za-z0-9._]*$"
              },
              "marketplace": {
                "type": "string",
                "minLength": 1,
                "pattern": "^[A-Za-z0-9][-A-Za-z0-9._]*$"
              }
            },
            "required": ["name"],
            "additionalProperties": {}
          }
        ]
      }
    },
    "hooks": {
      "anyOf": [
        {
          "description": "Path to file with additional hooks (in addition to those in hooks/hooks.json, if it exists), relative to the plugin root",
          "type": "string",
          "allOf": [
            {
              "type": "string",
              "pattern": "^\\.\\/.*"
            },
            {
              "type": "string",
              "pattern": ".*\\.json$"
            }
          ]
        },
        {
          "description": "Additional hooks (in addition to those in hooks/hooks.json, if it exists)",
          "type": "object",
          "propertyNames": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "PreToolUse",
                  "PostToolUse",
                  "PostToolUseFailure",
                  "PostToolBatch",
                  "Notification",
                  "UserPromptSubmit",
                  "UserPromptExpansion",
                  "SessionStart",
                  "SessionEnd",
                  "Stop",
                  "StopFailure",
                  "SubagentStart",
                  "SubagentStop",
                  "PreCompact",
                  "PostCompact",
                  "PermissionRequest",
                  "PermissionDenied",
                  "Setup",
                  "TeammateIdle",
                  "TaskCreated",
                  "TaskCompleted",
                  "Elicitation",
                  "ElicitationResult",
                  "ConfigChange",
                  "WorktreeCreate",
                  "WorktreeRemove",
                  "InstructionsLoaded",
                  "CwdChanged",
                  "FileChanged"
                ]
              },
              {
                "not": {}
              }
            ]
          },
          "additionalProperties": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "matcher": {
                  "description": "String pattern to match (e.g. tool names like \"Write\")",
                  "type": "string"
                },
                "hooks": {
                  "description": "List of hooks to execute when the matcher matches",
                  "type": "array",
                  "items": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "Shell command hook type",
                            "type": "string",
                            "const": "command"
                          },
                          "command": {
                            "description": "Shell command to execute",
                            "type": "string"
                          },
                          "if": {
                            "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                            "type": "string"
                          },
                          "shell": {
                            "description": "Shell interpreter. 'bash' uses your $SHELL (bash/zsh/sh); 'powershell' uses pwsh. Defaults to bash.",
                            "type": "string",
                            "enum": ["bash", "powershell"]
                          },
                          "timeout": {
                            "description": "Timeout in seconds for this specific command",
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "statusMessage": {
                            "description": "Custom status message to display in spinner while hook runs",
                            "type": "string"
                          },
                          "once": {
                            "description": "If true, hook runs once and is removed after execution",
                            "type": "boolean"
                          },
                          "async": {
                            "description": "If true, hook runs in background without blocking",
                            "type": "boolean"
                          },
                          "asyncRewake": {
                            "description": "If true, hook runs in background and wakes the model on exit code 2 (blocking error). Implies async.",
                            "type": "boolean"
                          }
                        },
                        "required": ["type", "command"]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "LLM prompt hook type",
                            "type": "string",
                            "const": "prompt"
                          },
                          "prompt": {
                            "description": "Prompt to evaluate with LLM. Use $ARGUMENTS placeholder for hook input JSON.",
                            "type": "string"
                          },
                          "if": {
                            "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                            "type": "string"
                          },
                          "timeout": {
                            "description": "Timeout in seconds for this specific prompt evaluation",
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "model": {
                            "description": "Model to use for this prompt hook (e.g., \"claude-sonnet-4-6\"). If not specified, uses the default small fast model.",
                            "type": "string"
                          },
                          "statusMessage": {
                            "description": "Custom status message to display in spinner while hook runs",
                            "type": "string"
                          },
                          "once": {
                            "description": "If true, hook runs once and is removed after execution",
                            "type": "boolean"
                          }
                        },
                        "required": ["type", "prompt"]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "Agentic verifier hook type",
                            "type": "string",
                            "const": "agent"
                          },
                          "prompt": {
                            "description": "Prompt describing what to verify (e.g. \"Verify that unit tests ran and passed.\"). Use $ARGUMENTS placeholder for hook input JSON.",
                            "type": "string"
                          },
                          "if": {
                            "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                            "type": "string"
                          },
                          "timeout": {
                            "description": "Timeout in seconds for agent execution (default 60)",
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "model": {
                            "description": "Model to use for this agent hook (e.g., \"claude-sonnet-4-6\"). If not specified, uses Haiku.",
                            "type": "string"
                          },
                          "statusMessage": {
                            "description": "Custom status message to display in spinner while hook runs",
                            "type": "string"
                          },
                          "once": {
                            "description": "If true, hook runs once and is removed after execution",
                            "type": "boolean"
                          }
                        },
                        "required": ["type", "prompt"]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "HTTP hook type",
                            "type": "string",
                            "const": "http"
                          },
                          "url": {
                            "description": "URL to POST the hook input JSON to",
                            "type": "string",
                            "format": "uri"
                          },
                          "if": {
                            "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                            "type": "string"
                          },
                          "timeout": {
                            "description": "Timeout in seconds for this specific request",
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "headers": {
                            "description": "Additional headers to include in the request. Values may reference environment variables using $VAR_NAME or ${VAR_NAME} syntax (e.g., \"Authorization\": \"Bearer $MY_TOKEN\"). Only variables listed in allowedEnvVars will be interpolated.",
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            }
                          },
                          "allowedEnvVars": {
                            "description": "Explicit list of environment variable names that may be interpolated in header values. Only variables listed here will be resolved; all other $VAR references are left as empty strings. Required for env var interpolation to work.",
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "statusMessage": {
                            "description": "Custom status message to display in spinner while hook runs",
                            "type": "string"
                          },
                          "once": {
                            "description": "If true, hook runs once and is removed after execution",
                            "type": "boolean"
                          }
                        },
                        "required": ["type", "url"]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "description": "MCP tool hook type",
                            "type": "string",
                            "const": "mcp_tool"
                          },
                          "server": {
                            "description": "Name of an already-configured MCP server to invoke",
                            "type": "string"
                          },
                          "tool": {
                            "description": "Name of the tool on that server to call",
                            "type": "string"
                          },
                          "input": {
                            "description": "Arguments passed to the MCP tool. String values support ${path} interpolation from the hook input JSON (e.g. \"${tool_input.file_path}\").",
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {}
                          },
                          "if": {
                            "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                            "type": "string"
                          },
                          "timeout": {
                            "description": "Timeout in seconds for this specific tool call",
                            "type": "number",
                            "exclusiveMinimum": 0
                          },
                          "statusMessage": {
                            "description": "Custom status message to display in spinner while hook runs",
                            "type": "string"
                          },
                          "once": {
                            "description": "If true, hook runs once and is removed after execution",
                            "type": "boolean"
                          }
                        },
                        "required": ["type", "server", "tool"]
                      }
                    ]
                  }
                }
              },
              "required": ["hooks"]
            }
          }
        },
        {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "description": "Path to file with additional hooks (in addition to those in hooks/hooks.json, if it exists), relative to the plugin root",
                "type": "string",
                "allOf": [
                  {
                    "type": "string",
                    "pattern": "^\\.\\/.*"
                  },
                  {
                    "type": "string",
                    "pattern": ".*\\.json$"
                  }
                ]
              },
              {
                "description": "Additional hooks (in addition to those in hooks/hooks.json, if it exists)",
                "type": "object",
                "propertyNames": {
                  "anyOf": [
                    {
                      "type": "string",
                      "enum": [
                        "PreToolUse",
                        "PostToolUse",
                        "PostToolUseFailure",
                        "PostToolBatch",
                        "Notification",
                        "UserPromptSubmit",
                        "UserPromptExpansion",
                        "SessionStart",
                        "SessionEnd",
                        "Stop",
                        "StopFailure",
                        "SubagentStart",
                        "SubagentStop",
                        "PreCompact",
                        "PostCompact",
                        "PermissionRequest",
                        "PermissionDenied",
                        "Setup",
                        "TeammateIdle",
                        "TaskCreated",
                        "TaskCompleted",
                        "Elicitation",
                        "ElicitationResult",
                        "ConfigChange",
                        "WorktreeCreate",
                        "WorktreeRemove",
                        "InstructionsLoaded",
                        "CwdChanged",
                        "FileChanged"
                      ]
                    },
                    {
                      "not": {}
                    }
                  ]
                },
                "additionalProperties": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "matcher": {
                        "description": "String pattern to match (e.g. tool names like \"Write\")",
                        "type": "string"
                      },
                      "hooks": {
                        "description": "List of hooks to execute when the matcher matches",
                        "type": "array",
                        "items": {
                          "anyOf": [
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "description": "Shell command hook type",
                                  "type": "string",
                                  "const": "command"
                                },
                                "command": {
                                  "description": "Shell command to execute",
                                  "type": "string"
                                },
                                "if": {
                                  "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                                  "type": "string"
                                },
                                "shell": {
                                  "description": "Shell interpreter. 'bash' uses your $SHELL (bash/zsh/sh); 'powershell' uses pwsh. Defaults to bash.",
                                  "type": "string",
                                  "enum": ["bash", "powershell"]
                                },
                                "timeout": {
                                  "description": "Timeout in seconds for this specific command",
                                  "type": "number",
                                  "exclusiveMinimum": 0
                                },
                                "statusMessage": {
                                  "description": "Custom status message to display in spinner while hook runs",
                                  "type": "string"
                                },
                                "once": {
                                  "description": "If true, hook runs once and is removed after execution",
                                  "type": "boolean"
                                },
                                "async": {
                                  "description": "If true, hook runs in background without blocking",
                                  "type": "boolean"
                                },
                                "asyncRewake": {
                                  "description": "If true, hook runs in background and wakes the model on exit code 2 (blocking error). Implies async.",
                                  "type": "boolean"
                                }
                              },
                              "required": ["type", "command"]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "description": "LLM prompt hook type",
                                  "type": "string",
                                  "const": "prompt"
                                },
                                "prompt": {
                                  "description": "Prompt to evaluate with LLM. Use $ARGUMENTS placeholder for hook input JSON.",
                                  "type": "string"
                                },
                                "if": {
                                  "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                                  "type": "string"
                                },
                                "timeout": {
                                  "description": "Timeout in seconds for this specific prompt evaluation",
                                  "type": "number",
                                  "exclusiveMinimum": 0
                                },
                                "model": {
                                  "description": "Model to use for this prompt hook (e.g., \"claude-sonnet-4-6\"). If not specified, uses the default small fast model.",
                                  "type": "string"
                                },
                                "statusMessage": {
                                  "description": "Custom status message to display in spinner while hook runs",
                                  "type": "string"
                                },
                                "once": {
                                  "description": "If true, hook runs once and is removed after execution",
                                  "type": "boolean"
                                }
                              },
                              "required": ["type", "prompt"]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "description": "Agentic verifier hook type",
                                  "type": "string",
                                  "const": "agent"
                                },
                                "prompt": {
                                  "description": "Prompt describing what to verify (e.g. \"Verify that unit tests ran and passed.\"). Use $ARGUMENTS placeholder for hook input JSON.",
                                  "type": "string"
                                },
                                "if": {
                                  "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                                  "type": "string"
                                },
                                "timeout": {
                                  "description": "Timeout in seconds for agent execution (default 60)",
                                  "type": "number",
                                  "exclusiveMinimum": 0
                                },
                                "model": {
                                  "description": "Model to use for this agent hook (e.g., \"claude-sonnet-4-6\"). If not specified, uses Haiku.",
                                  "type": "string"
                                },
                                "statusMessage": {
                                  "description": "Custom status message to display in spinner while hook runs",
                                  "type": "string"
                                },
                                "once": {
                                  "description": "If true, hook runs once and is removed after execution",
                                  "type": "boolean"
                                }
                              },
                              "required": ["type", "prompt"]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "description": "HTTP hook type",
                                  "type": "string",
                                  "const": "http"
                                },
                                "url": {
                                  "description": "URL to POST the hook input JSON to",
                                  "type": "string",
                                  "format": "uri"
                                },
                                "if": {
                                  "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                                  "type": "string"
                                },
                                "timeout": {
                                  "description": "Timeout in seconds for this specific request",
                                  "type": "number",
                                  "exclusiveMinimum": 0
                                },
                                "headers": {
                                  "description": "Additional headers to include in the request. Values may reference environment variables using $VAR_NAME or ${VAR_NAME} syntax (e.g., \"Authorization\": \"Bearer $MY_TOKEN\"). Only variables listed in allowedEnvVars will be interpolated.",
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {
                                    "type": "string"
                                  }
                                },
                                "allowedEnvVars": {
                                  "description": "Explicit list of environment variable names that may be interpolated in header values. Only variables listed here will be resolved; all other $VAR references are left as empty strings. Required for env var interpolation to work.",
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "statusMessage": {
                                  "description": "Custom status message to display in spinner while hook runs",
                                  "type": "string"
                                },
                                "once": {
                                  "description": "If true, hook runs once and is removed after execution",
                                  "type": "boolean"
                                }
                              },
                              "required": ["type", "url"]
                            },
                            {
                              "type": "object",
                              "properties": {
                                "type": {
                                  "description": "MCP tool hook type",
                                  "type": "string",
                                  "const": "mcp_tool"
                                },
                                "server": {
                                  "description": "Name of an already-configured MCP server to invoke",
                                  "type": "string"
                                },
                                "tool": {
                                  "description": "Name of the tool on that server to call",
                                  "type": "string"
                                },
                                "input": {
                                  "description": "Arguments passed to the MCP tool. String values support ${path} interpolation from the hook input JSON (e.g. \"${tool_input.file_path}\").",
                                  "type": "object",
                                  "propertyNames": {
                                    "type": "string"
                                  },
                                  "additionalProperties": {}
                                },
                                "if": {
                                  "description": "Permission rule syntax to filter when this hook runs (e.g., \"Bash(git *)\"). Only runs if the tool call matches the pattern. Avoids spawning hooks for non-matching commands.",
                                  "type": "string"
                                },
                                "timeout": {
                                  "description": "Timeout in seconds for this specific tool call",
                                  "type": "number",
                                  "exclusiveMinimum": 0
                                },
                                "statusMessage": {
                                  "description": "Custom status message to display in spinner while hook runs",
                                  "type": "string"
                                },
                                "once": {
                                  "description": "If true, hook runs once and is removed after execution",
                                  "type": "boolean"
                                }
                              },
                              "required": ["type", "server", "tool"]
                            }
                          ]
                        }
                      }
                    },
                    "required": ["hooks"]
                  }
                }
              }
            ]
          }
        }
      ]
    },
    "commands": {
      "anyOf": [
        {
          "description": "Path to additional command file or skill directory (in addition to those in the commands/ directory, if it exists), relative to the plugin root",
          "anyOf": [
            {
              "type": "string",
              "allOf": [
                {
                  "type": "string",
                  "pattern": "^\\.\\/.*"
                },
                {
                  "type": "string",
                  "pattern": ".*\\.md$"
                }
              ]
            },
            {
              "type": "string",
              "pattern": "^\\.\\/.*"
            }
          ]
        },
        {
          "description": "List of paths to additional command files or skill directories",
          "type": "array",
          "items": {
            "description": "Path to additional command file or skill directory (in addition to those in the commands/ directory, if it exists), relative to the plugin root",
            "anyOf": [
              {
                "type": "string",
                "allOf": [
                  {
                    "type": "string",
                    "pattern": "^\\.\\/.*"
                  },
                  {
                    "type": "string",
                    "pattern": ".*\\.md$"
                  }
                ]
              },
              {
                "type": "string",
                "pattern": "^\\.\\/.*"
              }
            ]
          }
        },
        {
          "description": "Object mapping of command names to their metadata and source files. Command name becomes the slash command name (e.g., \"about\" → \"/plugin:about\")",
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "object",
            "properties": {
              "source": {
                "description": "Path to command markdown file, relative to plugin root",
                "anyOf": [
                  {
                    "type": "string",
                    "allOf": [
                      {
                        "type": "string",
                        "pattern": "^\\.\\/.*"
                      },
                      {
                        "type": "string",
                        "pattern": ".*\\.md$"
                      }
                    ]
                  },
                  {
                    "type": "string",
                    "pattern": "^\\.\\/.*"
                  }
                ]
              },
              "content": {
                "description": "Inline markdown content for the command",
                "type": "string"
              },
              "description": {
                "description": "Command description override",
                "type": "string"
              },
              "argumentHint": {
                "description": "Hint for command arguments (e.g., \"[file]\")",
                "type": "string"
              },
              "model": {
                "description": "Default model for this command",
                "type": "string"
              },
              "allowedTools": {
                "description": "Tools allowed when command runs",
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      ]
    },
    "agents": {
      "anyOf": [
        {
          "description": "Path to additional agent file (in addition to those in the agents/ directory, if it exists), relative to the plugin root",
          "type": "string",
          "allOf": [
            {
              "type": "string",
              "pattern": "^\\.\\/.*"
            },
            {
              "type": "string",
              "pattern": ".*\\.md$"
            }
          ]
        },
        {
          "description": "List of paths to additional agent files",
          "type": "array",
          "items": {
            "description": "Path to additional agent file (in addition to those in the agents/ directory, if it exists), relative to the plugin root",
            "type": "string",
            "allOf": [
              {
                "type": "string",
                "pattern": "^\\.\\/.*"
              },
              {
                "type": "string",
                "pattern": ".*\\.md$"
              }
            ]
          }
        }
      ]
    },
    "skills": {
      "anyOf": [
        {
          "description": "Path to additional skill directory (in addition to those in the skills/ directory, if it exists), relative to the plugin root",
          "type": "string",
          "pattern": "^\\.\\/.*"
        },
        {
          "description": "List of paths to additional skill directories",
          "type": "array",
          "items": {
            "description": "Path to additional skill directory (in addition to those in the skills/ directory, if it exists), relative to the plugin root",
            "type": "string",
            "pattern": "^\\.\\/.*"
          }
        }
      ]
    },
    "outputStyles": {
      "anyOf": [
        {
          "description": "Path to additional output styles directory or file (in addition to those in the output-styles/ directory, if it exists), relative to the plugin root",
          "type": "string",
          "pattern": "^\\.\\/.*"
        },
        {
          "description": "List of paths to additional output styles directories or files",
          "type": "array",
          "items": {
            "description": "Path to additional output styles directory or file (in addition to those in the output-styles/ directory, if it exists), relative to the plugin root",
            "type": "string",
            "pattern": "^\\.\\/.*"
          }
        }
      ]
    },
    "themes": {
      "anyOf": [
        {
          "description": "Path to additional themes directory or file (in addition to those in the themes/ directory, if it exists), relative to the plugin root",
          "type": "string",
          "pattern": "^\\.\\/.*"
        },
        {
          "description": "List of paths to additional themes directories or files",
          "type": "array",
          "items": {
            "description": "Path to additional themes directory or file (in addition to those in the themes/ directory, if it exists), relative to the plugin root",
            "type": "string",
            "pattern": "^\\.\\/.*"
          }
        }
      ]
    },
    "channels": {
      "description": "Channels this plugin provides. Each entry declares an MCP server as a message channel and optionally specifies user configuration to prompt for at enable time.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "server": {
            "description": "Name of the MCP server this channel binds to. Must match a key in this plugin's mcpServers.",
            "type": "string",
            "minLength": 1
          },
          "displayName": {
            "description": "Human-readable name shown in the config dialog title (e.g., \"Telegram\"). Defaults to the server name.",
            "type": "string"
          },
          "userConfig": {
            "description": "Fields to prompt the user for when enabling this plugin in assistant mode. Saved values are substituted into ${user_config.KEY} references in the mcpServers env.",
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "object",
              "properties": {
                "type": {
                  "description": "Type of the configuration value",
                  "type": "string",
                  "enum": ["string", "number", "boolean", "directory", "file"]
                },
                "title": {
                  "description": "Human-readable label shown in the config dialog",
                  "type": "string"
                },
                "description": {
                  "description": "Help text shown beneath the field in the config dialog",
                  "type": "string"
                },
                "required": {
                  "description": "If true, validation fails when this field is empty",
                  "type": "boolean"
                },
                "default": {
                  "description": "Default value used when the user provides nothing",
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "number"
                    },
                    {
                      "type": "boolean"
                    },
                    {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  ]
                },
                "multiple": {
                  "description": "For string type: allow an array of strings",
                  "type": "boolean"
                },
                "sensitive": {
                  "description": "If true, masks dialog input and stores value in secure storage (keychain/credentials file) instead of settings.json",
                  "type": "boolean"
                },
                "min": {
                  "description": "Minimum value (number type only)",
                  "type": "number"
                },
                "max": {
                  "description": "Maximum value (number type only)",
                  "type": "number"
                }
              },
              "required": ["type", "title", "description"],
              "additionalProperties": false
            }
          }
        },
        "required": ["server"],
        "additionalProperties": false
      }
    },
    "mcpServers": {
      "anyOf": [
        {
          "description": "MCP servers to include in the plugin (in addition to those in the .mcp.json file, if it exists)",
          "type": "string",
          "allOf": [
            {
              "type": "string",
              "pattern": "^\\.\\/.*"
            },
            {
              "type": "string",
              "pattern": ".*\\.json$"
            }
          ]
        },
        {
          "description": "Path or URL to MCPB file containing MCP server configuration",
          "anyOf": [
            {
              "description": "Path to MCPB file relative to plugin root",
              "type": "string",
              "pattern": "^\\.\\/.*"
            },
            {
              "description": "URL to MCPB file",
              "type": "string",
              "format": "uri"
            }
          ]
        },
        {
          "description": "MCP server configurations keyed by server name",
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "stdio"
                  },
                  "command": {
                    "type": "string",
                    "minLength": 1
                  },
                  "args": {
                    "default": [],
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "env": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    }
                  }
                },
                "required": ["command"]
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "sse"
                  },
                  "url": {
                    "type": "string"
                  },
                  "headers": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "headersHelper": {
                    "type": "string"
                  },
                  "oauth": {
                    "type": "object",
                    "properties": {
                      "clientId": {
                        "type": "string"
                      },
                      "callbackPort": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "maximum": 9007199254740991
                      },
                      "authServerMetadataUrl": {
                        "type": "string",
                        "format": "uri",
                        "pattern": "^https:\\/\\/.*"
                      },
                      "scopes": {
                        "type": "string",
                        "minLength": 1
                      },
                      "xaa": {
                        "type": "boolean"
                      }
                    }
                  }
                },
                "required": ["type", "url"]
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "http"
                  },
                  "url": {
                    "type": "string"
                  },
                  "headers": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "headersHelper": {
                    "type": "string"
                  },
                  "oauth": {
                    "type": "object",
                    "properties": {
                      "clientId": {
                        "type": "string"
                      },
                      "callbackPort": {
                        "type": "integer",
                        "exclusiveMinimum": 0,
                        "maximum": 9007199254740991
                      },
                      "authServerMetadataUrl": {
                        "type": "string",
                        "format": "uri",
                        "pattern": "^https:\\/\\/.*"
                      },
                      "scopes": {
                        "type": "string",
                        "minLength": 1
                      },
                      "xaa": {
                        "type": "boolean"
                      }
                    }
                  }
                },
                "required": ["type", "url"]
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "ws"
                  },
                  "url": {
                    "type": "string"
                  },
                  "headers": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "headersHelper": {
                    "type": "string"
                  }
                },
                "required": ["type", "url"]
              }
            ]
          }
        },
        {
          "description": "Array of MCP server configurations (paths, MCPB files, or inline definitions)",
          "type": "array",
          "items": {
            "anyOf": [
              {
                "description": "Path to MCP servers configuration file",
                "type": "string",
                "allOf": [
                  {
                    "type": "string",
                    "pattern": "^\\.\\/.*"
                  },
                  {
                    "type": "string",
                    "pattern": ".*\\.json$"
                  }
                ]
              },
              {
                "description": "Path or URL to MCPB file",
                "anyOf": [
                  {
                    "description": "Path to MCPB file relative to plugin root",
                    "type": "string",
                    "pattern": "^\\.\\/.*"
                  },
                  {
                    "description": "URL to MCPB file",
                    "type": "string",
                    "format": "uri"
                  }
                ]
              },
              {
                "description": "Inline MCP server configurations",
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "stdio"
                        },
                        "command": {
                          "type": "string",
                          "minLength": 1
                        },
                        "args": {
                          "default": [],
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "env": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string"
                          }
                        }
                      },
                      "required": ["command"]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "sse"
                        },
                        "url": {
                          "type": "string"
                        },
                        "headers": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string"
                          }
                        },
                        "headersHelper": {
                          "type": "string"
                        },
                        "oauth": {
                          "type": "object",
                          "properties": {
                            "clientId": {
                              "type": "string"
                            },
                            "callbackPort": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "maximum": 9007199254740991
                            },
                            "authServerMetadataUrl": {
                              "type": "string",
                              "format": "uri",
                              "pattern": "^https:\\/\\/.*"
                            },
                            "scopes": {
                              "type": "string",
                              "minLength": 1
                            },
                            "xaa": {
                              "type": "boolean"
                            }
                          }
                        }
                      },
                      "required": ["type", "url"]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "http"
                        },
                        "url": {
                          "type": "string"
                        },
                        "headers": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string"
                          }
                        },
                        "headersHelper": {
                          "type": "string"
                        },
                        "oauth": {
                          "type": "object",
                          "properties": {
                            "clientId": {
                              "type": "string"
                            },
                            "callbackPort": {
                              "type": "integer",
                              "exclusiveMinimum": 0,
                              "maximum": 9007199254740991
                            },
                            "authServerMetadataUrl": {
                              "type": "string",
                              "format": "uri",
                              "pattern": "^https:\\/\\/.*"
                            },
                            "scopes": {
                              "type": "string",
                              "minLength": 1
                            },
                            "xaa": {
                              "type": "boolean"
                            }
                          }
                        }
                      },
                      "required": ["type", "url"]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "ws"
                        },
                        "url": {
                          "type": "string"
                        },
                        "headers": {
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string"
                          }
                        },
                        "headersHelper": {
                          "type": "string"
                        }
                      },
                      "required": ["type", "url"]
                    }
                  ]
                }
              }
            ]
          }
        }
      ]
    },
    "lspServers": {
      "anyOf": [
        {
          "description": "Path to .lsp.json configuration file relative to plugin root",
          "type": "string",
          "allOf": [
            {
              "type": "string",
              "pattern": "^\\.\\/.*"
            },
            {
              "type": "string",
              "pattern": ".*\\.json$"
            }
          ]
        },
        {
          "description": "LSP server configurations keyed by server name",
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "object",
            "properties": {
              "command": {
                "description": "Command to execute the LSP server (e.g., \"typescript-language-server\")",
                "type": "string",
                "minLength": 1
              },
              "args": {
                "description": "Command-line arguments to pass to the server",
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1
                }
              },
              "extensionToLanguage": {
                "description": "Mapping from file extension to LSP language ID. File extensions and languages are derived from this mapping.",
                "type": "object",
                "propertyNames": {
                  "type": "string",
                  "minLength": 2
                },
                "additionalProperties": {
                  "type": "string",
                  "minLength": 1
                }
              },
              "transport": {
                "description": "Communication transport mechanism",
                "default": "stdio",
                "type": "string",
                "enum": ["stdio", "socket"]
              },
              "env": {
                "description": "Environment variables to set when starting the server",
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "type": "string"
                }
              },
              "initializationOptions": {
                "description": "Initialization options passed to the server during initialization"
              },
              "settings": {
                "description": "Settings passed to the server via workspace/didChangeConfiguration"
              },
              "workspaceFolder": {
                "description": "Workspace folder path to use for the server",
                "type": "string"
              },
              "startupTimeout": {
                "description": "Maximum time to wait for server startup (milliseconds)",
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "shutdownTimeout": {
                "description": "Maximum time to wait for graceful shutdown (milliseconds)",
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "restartOnCrash": {
                "description": "Whether to restart the server if it crashes",
                "type": "boolean"
              },
              "maxRestarts": {
                "description": "Maximum number of restart attempts before giving up",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              }
            },
            "required": ["command", "extensionToLanguage"],
            "additionalProperties": false
          }
        },
        {
          "description": "Array of LSP server configurations (paths or inline definitions)",
          "type": "array",
          "items": {
            "anyOf": [
              {
                "description": "Path to LSP configuration file",
                "type": "string",
                "allOf": [
                  {
                    "type": "string",
                    "pattern": "^\\.\\/.*"
                  },
                  {
                    "type": "string",
                    "pattern": ".*\\.json$"
                  }
                ]
              },
              {
                "description": "Inline LSP server configurations",
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "command": {
                      "description": "Command to execute the LSP server (e.g., \"typescript-language-server\")",
                      "type": "string",
                      "minLength": 1
                    },
                    "args": {
                      "description": "Command-line arguments to pass to the server",
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1
                      }
                    },
                    "extensionToLanguage": {
                      "description": "Mapping from file extension to LSP language ID. File extensions and languages are derived from this mapping.",
                      "type": "object",
                      "propertyNames": {
                        "type": "string",
                        "minLength": 2
                      },
                      "additionalProperties": {
                        "type": "string",
                        "minLength": 1
                      }
                    },
                    "transport": {
                      "description": "Communication transport mechanism",
                      "default": "stdio",
                      "type": "string",
                      "enum": ["stdio", "socket"]
                    },
                    "env": {
                      "description": "Environment variables to set when starting the server",
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string"
                      }
                    },
                    "initializationOptions": {
                      "description": "Initialization options passed to the server during initialization"
                    },
                    "settings": {
                      "description": "Settings passed to the server via workspace/didChangeConfiguration"
                    },
                    "workspaceFolder": {
                      "description": "Workspace folder path to use for the server",
                      "type": "string"
                    },
                    "startupTimeout": {
                      "description": "Maximum time to wait for server startup (milliseconds)",
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    },
                    "shutdownTimeout": {
                      "description": "Maximum time to wait for graceful shutdown (milliseconds)",
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    },
                    "restartOnCrash": {
                      "description": "Whether to restart the server if it crashes",
                      "type": "boolean"
                    },
                    "maxRestarts": {
                      "description": "Maximum number of restart attempts before giving up",
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    }
                  },
                  "required": ["command", "extensionToLanguage"],
                  "additionalProperties": false
                }
              }
            ]
          }
        }
      ]
    },
    "monitors": {
      "description": "Background watch scripts the host arms as persistent Monitor tasks (unsandboxed, same trust tier as hooks) so plugins need not instruct the model to arm them. When omitted, monitors/monitors.json at the plugin root is loaded if present.",
      "anyOf": [
        {
          "description": "Path to a JSON file containing the monitors array, relative to the plugin root",
          "type": "string",
          "allOf": [
            {
              "type": "string",
              "pattern": "^\\.\\/.*"
            },
            {
              "type": "string",
              "pattern": ".*\\.json$"
            }
          ]
        },
        {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "description": "Identifier for this monitor, unique within the plugin. Used to dedupe so re-arming (plugin reload, repeat skill invoke) does not spawn duplicates.",
                "type": "string",
                "minLength": 1
              },
              "command": {
                "description": "Shell command to run as a persistent background monitor. Each stdout line is delivered to the model as a <task_notification> event; the process runs for the session lifetime. ${CLAUDE_PLUGIN_ROOT}, ${CLAUDE_PLUGIN_DATA}, ${user_config.*}, and ${ENV_VAR} are substituted. Runs in the session cwd — prefix with `cd \"${CLAUDE_PLUGIN_ROOT}\" && ` if the script needs its own directory.",
                "type": "string",
                "minLength": 1
              },
              "description": {
                "description": "Short human-readable description of what is being monitored (shown in task panel and notification summary).",
                "type": "string",
                "minLength": 1
              },
              "when": {
                "description": "Arm trigger. \"always\" arms at session start and on plugin reload. \"on-skill-invoke:<skill>\" arms the first time that skill is dispatched (via Skill tool or slash command).",
                "default": "always",
                "anyOf": [
                  {
                    "type": "string",
                    "const": "always"
                  },
                  {
                    "type": "string",
                    "pattern": "^on-skill-invoke:.*"
                  }
                ]
              }
            },
            "required": ["name", "command", "description"],
            "additionalProperties": false
          }
        }
      ]
    },
    "settings": {
      "description": "Settings to merge into the user settings while this plugin is enabled. Only the documented allowlisted keys are applied.",
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "userConfig": {
      "description": "User-configurable values this plugin needs. Prompted at enable time. Non-sensitive values saved to settings.json; sensitive values to secure storage. Available as ${user_config.KEY} in MCP/LSP server config, hook commands, and (non-sensitive only) skill/agent content. Keep sensitive value counts small.",
      "type": "object",
      "propertyNames": {
        "type": "string",
        "pattern": "^[A-Za-z_]\\w*$"
      },
      "additionalProperties": {
        "type": "object",
        "properties": {
          "type": {
            "description": "Type of the configuration value",
            "type": "string",
            "enum": ["string", "number", "boolean", "directory", "file"]
          },
          "title": {
            "description": "Human-readable label shown in the config dialog",
            "type": "string"
          },
          "description": {
            "description": "Help text shown beneath the field in the config dialog",
            "type": "string"
          },
          "required": {
            "description": "If true, validation fails when this field is empty",
            "type": "boolean"
          },
          "default": {
            "description": "Default value used when the user provides nothing",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "multiple": {
            "description": "For string type: allow an array of strings",
            "type": "boolean"
          },
          "sensitive": {
            "description": "If true, masks dialog input and stores value in secure storage (keychain/credentials file) instead of settings.json",
            "type": "boolean"
          },
          "min": {
            "description": "Minimum value (number type only)",
            "type": "number"
          },
          "max": {
            "description": "Maximum value (number type only)",
            "type": "number"
          }
        },
        "required": ["type", "title", "description"],
        "additionalProperties": false
      }
    }
  },
  "required": ["name"],
  "title": "Claude Code Plugin Manifest",
  "description": "Manifest (.claude-plugin/plugin.json) for a Claude Code plugin. Learn more: https://code.claude.com/docs/en/plugins-reference"
}
