Retour aux articles
11 MIN READ

Claude Code Plugins: Create & Distribute Extensions

By Learnia Team

Claude Code Plugins: Create & Distribute Extensions

This article is written in English. Our training modules are available in French.

Plugins extend Claude Code beyond its built-in capabilities. They add new tools, integrations, and functionality—packaged for easy installation and sharing. Whether you need specialized development tools or want to share your innovations with the community, plugins make it possible.


What Are Plugins?

Plugins are self-contained packages that add features to Claude Code:

  • New tools: Additional commands Claude can use
  • Integrations: Connections to services and APIs
  • Workflows: Pre-built automation patterns
  • UI extensions: Custom visualizations and interfaces

Example: Without a Plugin

> Analyze this image for accessibility issues

I don't have image analysis capabilities in this context.

Example: With Vision Plugin

> Analyze this image for accessibility issues

[Vision Plugin: Analyzing image...]

Accessibility Issues Found:
1. Low contrast ratio (2.1:1) on header text
2. Missing alt text suggestion: "Product showcase banner"
3. Color-only information in the chart (needs patterns)

Recommendations:
- Increase text contrast to 4.5:1
- Add descriptive alt text
- Add patterns to distinguish chart segments

Plugin Architecture

Plugin Stack (from top to bottom):

  1. Claude Code (main application)
  2. Plugins Layer → Vision, DB, AWS, Custom plugins
  3. Plugin API Layer → Standardized interface
  4. Core Claude Code → Base functionality

Plugins interact with Claude Code through:

  • Tool Registration: Declare available tools
  • Hook Integration: Subscribe to lifecycle events
  • MCP Extensions: Add new MCP servers
  • Configuration: Settings and preferences

Managing Plugins

List Installed Plugins

> /plugin list

Installed Plugins:

  vision@1.2.0 - Image and vision analysis
  db-explorer@2.0.1 - Database exploration tools
  aws-toolkit@1.5.0 - AWS service integration

Marketplace: https://plugins.claude.ai

Install a Plugin

> /plugin install vision

Installing vision@latest...

✓ Downloaded vision@1.2.0
✓ Verified signature
✓ Registered 3 new tools:
  - analyze_image
  - extract_text
  - describe_scene

Plugin installed successfully.

From a specific source:

# From npm
claude plugin install @anthropic/vision-plugin

# From GitHub
claude plugin install github:username/my-plugin

# From local path
claude plugin install ./my-local-plugin

Update Plugins

> /plugin update vision

Updating vision...
1.2.0 → 1.3.0

Changes:
- Added video frame analysis
- Improved text extraction accuracy
- Bug fixes

✓ Updated successfully

Update all plugins:

> /plugin update --all

Remove Plugins

> /plugin remove vision

Remove vision plugin? This will unregister its tools.
[y/n]: y

✓ Plugin removed

Plugin Configuration

View Plugin Settings

> /plugin config vision

Vision Plugin Settings:

  model: gpt-4-vision (default)
  max_image_size: 4MB
  output_format: markdown
  cache_results: true

[e] Edit settings  [r] Reset to defaults  [Esc] Exit

Configure Plugin

> /plugin config vision set output_format json

Updated: output_format = json

Plugin Settings File

// ~/.claude/plugins/vision/config.json
{
  "model": "gpt-4-vision",
  "max_image_size": "4MB",
  "output_format": "json",
  "cache_results": true,
  "api_key": "${VISION_API_KEY}"
}

Creating Plugins

Plugin Structure

A plugin folder contains:

  • package.json - Plugin metadata
  • index.js - Main entry point
  • tools/my-tool.js - Tool definitions
  • tools/another-tool.js - Additional tools
  • hooks/on-start.js - Lifecycle hooks
  • config.schema.json - Configuration schema
  • README.md - Documentation

package.json

{
  "name": "@myorg/my-plugin",
  "version": "1.0.0",
  "description": "My custom Claude Code plugin",
  "claudeCode": {
    "type": "plugin",
    "displayName": "My Plugin",
    "icon": "puzzle",
    "minVersion": "1.0.0"
  },
  "main": "index.js",
  "keywords": ["claude-code-plugin"],
  "author": "Your Name",
  "license": "MIT"
}

Main Entry Point

// index.js
export default {
  name: "my-plugin",
  version: "1.0.0",
  
  // Tools this plugin provides
  tools: [
    require("./tools/my-tool"),
    require("./tools/another-tool")
  ],
  
  // Lifecycle hooks
  hooks: {
    onLoad: async (context) => {
      console.log("Plugin loaded");
    },
    onUnload: async (context) => {
      console.log("Plugin unloaded");
    }
  },
  
  // Configuration schema
  configSchema: require("./config.schema.json")
};

Defining Tools

// tools/my-tool.js
export default {
  name: "analyze_complexity",
  description: "Analyze code complexity metrics",
  
  inputSchema: {
    type: "object",
    properties: {
      filePath: {
        type: "string",
        description: "Path to file to analyze"
      },
      metrics: {
        type: "array",
        items: { type: "string" },
        description: "Metrics to calculate",
        default: ["cyclomatic", "cognitive", "halstead"]
      }
    },
    required: ["filePath"]
  },
  
  async execute(input, context) {
    const { filePath, metrics } = input;
    
    // Read file using context
    const content = await context.readFile(filePath);
    
    // Calculate metrics
    const results = calculateMetrics(content, metrics);
    
    return {
      content: [{
        type: "text",
        text: JSON.stringify(results, null, 2)
      }]
    };
  }
};

function calculateMetrics(content, metrics) {
  // Implementation...
  return {
    cyclomatic: 5,
    cognitive: 8,
    halstead: { difficulty: 12.5 }
  };
}

Plugin API

Context Object

Plugins receive a context object with Claude Code APIs:

async execute(input, context) {
  // File operations
  const content = await context.readFile(path);
  await context.writeFile(path, content);
  
  // Run commands
  const result = await context.runCommand("npm test");
  
  // Access configuration
  const config = context.getConfig();
  
  // Logging
  context.log.info("Processing...");
  context.log.error("Something went wrong");
  
  // User interaction
  const answer = await context.prompt("Continue? [y/n]");
  
  // Progress reporting
  context.progress.start("Analyzing...");
  context.progress.update(50, "Halfway done");
  context.progress.complete("Done!");
}

Tool Response Format

return {
  content: [
    {
      type: "text",
      text: "Analysis complete"
    },
    {
      type: "code",
      language: "json",
      text: JSON.stringify(data)
    }
  ],
  metadata: {
    cached: true,
    duration: 1234
  }
};

Error Handling

async execute(input, context) {
  try {
    const result = await riskyOperation();
    return { content: [{ type: "text", text: result }] };
  } catch (error) {
    return {
      error: {
        code: "OPERATION_FAILED",
        message: error.message,
        recoverable: true
      }
    };
  }
}

Plugin Types

Tool Plugins

Add new capabilities:

// Image analysis plugin
export default {
  name: "vision-tools",
  tools: [
    {
      name: "analyze_image",
      description: "Analyze image contents",
      async execute({ imagePath }, context) {
        const image = await context.readFile(imagePath, "base64");
        const analysis = await visionAPI.analyze(image);
        return { content: [{ type: "text", text: analysis }] };
      }
    }
  ]
};

Integration Plugins

Connect to external services:

// Jira integration plugin
export default {
  name: "jira-integration",
  tools: [
    {
      name: "get_jira_issue",
      description: "Fetch Jira issue details",
      async execute({ issueKey }, context) {
        const config = context.getConfig();
        const jira = new JiraClient(config.apiKey);
        const issue = await jira.getIssue(issueKey);
        return { content: [{ type: "text", text: formatIssue(issue) }] };
      }
    },
    {
      name: "create_jira_issue",
      description: "Create new Jira issue",
      async execute({ summary, description, type }, context) {
        // Implementation...
      }
    }
  ]
};

Workflow Plugins

Provide complex multi-step operations:

// Release automation plugin
export default {
  name: "release-automation",
  tools: [
    {
      name: "prepare_release",
      description: "Prepare a new release",
      async execute({ version, changelog }, context) {
        // 1. Update version
        await context.runCommand(`npm version ${version}`);
        
        // 2. Generate changelog
        const changes = await generateChangelog();
        await context.writeFile("CHANGELOG.md", changes);
        
        // 3. Create commit
        await context.runCommand("git add -A");
        await context.runCommand(`git commit -m "Release ${version}"`);
        
        // 4. Create tag
        await context.runCommand(`git tag v${version}`);
        
        return {
          content: [{
            type: "text",
            text: `Release ${version} prepared. Run 'git push --tags' to publish.`
          }]
        };
      }
    }
  ]
};

Hook Plugins

React to Claude Code events:

// Analytics plugin
export default {
  name: "analytics",
  hooks: {
    onToolUse: async (event, context) => {
      await analytics.track("tool_used", {
        tool: event.toolName,
        duration: event.duration
      });
    },
    onSessionStart: async (context) => {
      await analytics.track("session_started");
    },
    onSessionEnd: async (context) => {
      await analytics.track("session_ended", {
        duration: context.sessionDuration
      });
    }
  }
};

Publishing Plugins

Prepare for Publication

  1. Test thoroughly:
npm test
claude plugin validate ./my-plugin
  1. Add documentation:
<!-- README.md -->
# My Plugin

## Installation
\`\`\`
claude plugin install @myorg/my-plugin
\`\`\`

## Tools

### analyze_complexity
Analyzes code complexity metrics.

**Parameters:**
- `filePath` (required): Path to analyze
- `metrics` (optional): Array of metrics

**Example:**
\`\`\`
> Analyze complexity of src/utils.ts
\`\`\`
  1. Create config schema:
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "threshold": {
      "type": "number",
      "default": 10,
      "description": "Complexity threshold for warnings"
    }
  }
}

Publish to npm

npm publish --access public

Publish to Plugin Marketplace

claude plugin publish

Publishing @myorg/my-plugin@1.0.0...

✓ Validated plugin structure
✓ Scanned for security issues
✓ Generated documentation
✓ Submitted for review

Your plugin will be reviewed within 24-48 hours.
Track status: https://plugins.claude.ai/submissions/abc123

Private Distribution

For internal plugins:

# Install from private npm
claude plugin install @internal/my-plugin --registry https://npm.internal.com

# Install from private GitHub
claude plugin install github:org/private-plugin --token $GITHUB_TOKEN

Plugin Security

Permissions

Plugins declare required permissions:

{
  "claudeCode": {
    "permissions": {
      "filesystem": {
        "read": ["**/*.ts", "**/*.js"],
        "write": ["reports/**"]
      },
      "network": ["api.example.com"],
      "commands": ["npm:*"]
    }
  }
}

Users approve permissions on install:

Installing my-plugin...

This plugin requests:
✓ Read TypeScript/JavaScript files
✓ Write to reports/ directory
✓ Network access to api.example.com
✓ Run npm commands

Install with these permissions? [y/n]

Sandboxing

Plugins run in isolated environments:

  • Limited filesystem access
  • Controlled network access
  • No direct system calls
  • Memory limits

Verification

Marketplace plugins are verified:

  • Code review
  • Security scanning
  • Signature verification
> /plugin info vision

Vision Plugin
Publisher: Anthropic (verified ✓)
Downloads: 45,230
Rating: 4.8/5
Security: Scanned ✓
Signature: Valid ✓

Popular Plugin Categories

Development Tools

PluginDescription
complexity-analyzer
Code complexity metrics
dep-graph
Dependency visualization
perf-profiler
Performance analysis
code-coverage
Test coverage reporting

Integrations

PluginDescription
jira-tools
Jira issue management
linear-sync
Linear integration
figma-bridge
Figma design access
datadog-metrics
Monitoring data

AI/ML

PluginDescription
vision
Image analysis
embeddings
Semantic search
translation
Code translation
summarizer
Large file summaries

DevOps

PluginDescription
k8s-helper
Kubernetes tools
terraform-assist
IaC support
docker-tools
Container management
ci-monitor
CI/CD monitoring

Plugin Development Best Practices

1. Single Responsibility

Each tool should do one thing well:

// Good: Focused tools
{
  name: "get_user",
  // Only fetches user
}
{
  name: "update_user",
  // Only updates user
}

// Bad: Kitchen sink tool
{
  name: "manage_user",
  // Does too many things
}

2. Clear Descriptions

Help Claude understand when to use tools:

{
  name: "analyze_bundle_size",
  description: "Analyze JavaScript bundle size and identify large dependencies. " +
               "Use this when optimizing build output or investigating slow page loads. " +
               "Returns a breakdown of bundle contents with size in bytes."
}

3. Robust Error Handling

async execute(input, context) {
  if (!input.filePath) {
    return {
      error: {
        code: "MISSING_PARAMETER",
        message: "filePath is required"
      }
    };
  }
  
  try {
    const result = await analyze(input.filePath);
    return { content: [{ type: "text", text: result }] };
  } catch (error) {
    if (error.code === "ENOENT") {
      return {
        error: {
          code: "FILE_NOT_FOUND",
          message: `File not found: ${input.filePath}`
        }
      };
    }
    throw error; // Re-throw unexpected errors
  }
}

4. Efficient Resource Use

// Cache expensive operations
const cache = new Map();

async execute(input, context) {
  const cacheKey = JSON.stringify(input);
  
  if (cache.has(cacheKey)) {
    return cache.get(cacheKey);
  }
  
  const result = await expensiveOperation(input);
  cache.set(cacheKey, result);
  
  return result;
}

5. Version Compatibility

{
  "claudeCode": {
    "minVersion": "1.0.0",
    "maxVersion": "2.x"
  }
}

Integration with Other Features

Plugins + MCP

Plugins can register as MCP servers:

export default {
  name: "my-plugin",
  mcp: {
    serverName: "my-mcp-server",
    tools: [/* ... */]
  }
};

See Model Context Protocol (MCP) for Claude Code: Complete Guide.

Plugins + Hooks

Plugins can define hooks:

export default {
  hooks: {
    PreToolUse: async (event, context) => {
      // Validate before any tool runs
    }
  }
};

See Claude Code Hooks: Automate Your Development Workflow.

Plugins + Custom Commands

Commands can use plugin tools:

<!-- .claude/commands/analyze.md -->
Use the complexity-analyzer plugin to analyze this codebase
and generate a report.

See Custom Slash Commands in Claude Code: Build Your Own.


Key Takeaways

  1. Plugins extend capabilities: Add tools, integrations, and workflows.

  2. Easy installation:

    /plugin install
    handles everything.

  3. Security first: Plugins declare permissions and run sandboxed.

  4. Share with community: Publish to npm or the marketplace.

  5. Build custom solutions: Create plugins for your team's needs.


Build Production-Ready Extensions

Plugins are production code. Learn the principles of building reliable, maintainable software.

In our Module 4 — Code Generation, you'll learn:

  • Writing maintainable code
  • Testing strategies
  • Error handling patterns
  • Documentation best practices

Explore Module 4: Code Generation

GO DEEPER

Module 4 — Chaining & Routing

Build multi-step prompt workflows with conditional logic.