How Commands Are Defined and Invoked in Claude Plugins: A Complete Technical Guide

Claude plugins define commands declaratively in plugin.json and invoke them through a runtime dispatch process that validates arguments against JSON Schema before executing the associated skill folder.

Commands are the primary interface between Claude and external functionality in the anthropics/claude-plugins-community ecosystem. Each command represents a contract: the plugin manifest declares what the command does and what arguments it accepts, while the skill folder contains the implementation logic that executes when Claude decides to invoke it.

Command Definition in the Plugin Manifest

All command definitions reside in the .claude-plugin/plugin.json file at the root of each plugin repository. This manifest serves as the single source of truth for Claude's understanding of available capabilities.

The plugin.json Structure

The "commands" array contains objects with five critical fields:

  • name – The unique identifier Claude uses when calling the command (e.g., create_report)
  • description – Natural language explanation that helps Claude determine when to use the command
  • parameters – A JSON-Schema object defining argument types, required fields, and validation constraints
  • skill – Relative path to the skill folder containing the implementation (e.g., skills/tres-report-create)
  • example (optional) – Sample invocation demonstrating proper argument structure

According to the source code in the Tres Finance plugin, this declarative approach allows Claude to validate inputs before runtime, eliminating entire classes of execution errors.

JSON Schema for Parameters

The parameters field follows standard JSON-Schema specifications, enabling strict type checking:

{
  "name": "create_report",
  "description": "Generate a financial report for a given period.",
  "parameters": {
    "type": "object",
    "properties": {
      "start_date": { "type": "string", "format": "date" },
      "end_date": { "type": "string", "format": "date" },
      "report_type": { "type": "string", "enum": ["summary", "detailed"] }
    },
    "required": ["start_date", "end_date"]
  },
  "skill": "skills/tres-report-create"
}

Source: [.claude-plugin/plugin.json in the Tres Finance plugin](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/.claude-plugin/plugin.json).

This schema ensures that Claude only invokes create_report when it can provide valid start_date and end_date strings, and restricts report_type to the enumerated values.

Command Invocation Flow

When Claude determines a user request requires external functionality, the Claude runtime executes a five-step dispatch sequence.

Runtime Dispatch Process

  1. Intent Recognition – Claude analyzes the conversation context and selects the appropriate command name from the manifest
  2. Argument Validation – The runtime validates the generated JSON payload against the command's schema
  3. Skill Resolution – The system looks up the "skill" path in plugin.json (e.g., skills/tres-report-create)
  4. Module Loading – The runtime imports the skill's entry point, typically a run.py or run.js file
  5. Execution & Response – The skill processes the arguments and returns a JSON-serializable object to Claude

This separation between declaration (manifest) and execution (skill) allows developers to modify implementation logic without changing the external interface.

Skill Execution

The skill folder contains both documentation and code. Every skill includes:

  • SKILL.md – Human-readable documentation explaining the skill's purpose and usage patterns
  • Implementation scripts – Usually in scripts/ or src/ directories
  • Entry point function – Typically a run(args) function that accepts the validated arguments dictionary

Here is the implementation from skills/tres-report-create/:

import json
from datetime import datetime

def run(args):
    start = datetime.fromisoformat(args["start_date"])
    end = datetime.fromisoformat(args["end_date"])
    kind = args.get("report_type", "summary")

    # Placeholder logic – in production this queries databases or services

    report = {
        "type": kind,
        "period": f"{start.date()} → {end.date()}",
        "total_transactions": 42,
        "total_amount": 12345.67
    }
    return {"status": "success", "report": report}

Source: Example implementation pattern based on [run_report_matrix.py](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-report-create/tests/run_report_matrix.py).

The function receives the JSON payload as a Python dictionary, performs the business logic, and returns a dictionary that Claude serializes into the conversation.

Practical Implementation Examples

Declaring Multiple Commands

A single plugin can expose multiple capabilities by extending the "commands" array:

{
  "name": "tres-finance",
  "description": "Finance-related utilities for Tres.",
  "commands": [
    {
      "name": "create_report",
      "skill": "skills/tres-report-create"
    },
    {
      "name": "audit_transactions",
      "skill": "skills/tres-audit"
    }
  ]
}

Each command maps to a distinct skill folder, enabling modular architecture.

Runtime Invocation Payload

When Claude calls a command, it sends a structured request:

{
  "command": "create_report",
  "arguments": {
    "start_date": "2024-01-01",
    "end_date": "2024-01-31",
    "report_type": "detailed"
  }
}

The runtime extracts "create_report", locates the entry in plugin.json, loads skills/tres-report-create/, and invokes run({"start_date": "2024-01-01", ...}).

Summary

  • Declarative definition: Commands are defined in .claude-plugin/plugin.json using JSON-Schema for parameter validation
  • Separation of concerns: The manifest describes the interface while the skill folder (SKILL.md + code files) contains the implementation
  • Runtime dispatch: Claude validates arguments, loads the specified skill path, and executes the entry point function
  • Extensible architecture: Adding commands requires only editing plugin.json and creating a new skill folder—no core runtime changes needed

Frequently Asked Questions

What is the role of plugin.json in Claude plugins?

The .claude-plugin/plugin.json file serves as the manifest that declares all available commands, their parameters, and their associated skill implementations. Claude reads this file during plugin initialization to understand what capabilities are available and how to validate arguments before invoking any functionality.

How does Claude validate command arguments before execution?

Claude uses the JSON-Schema defined in the "parameters" field of each command entry. When the model generates a function call, the runtime validates the JSON payload against this schema, checking types, required fields, and enumerated values before passing the arguments to the skill's run() function.

What files are required to implement a new command?

You need three components: an entry in .claude-plugin/plugin.json defining the command schema and skill path; a SKILL.md file in the skill folder documenting the functionality; and an implementation file (typically run.py or run.js) containing the execution logic with a run(args) entry point.

How does the runtime locate and execute skill code?

The runtime reads the "skill" field from the command definition in plugin.json, which contains a relative path like skills/tres-report-create. It then loads this folder and executes the skill's entry point function, passing the validated JSON arguments as a dictionary or object.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →