How to Define API Endpoints for a Claude Plugin: Complete Implementation Guide

Claude plugins expose capabilities through HTTP API endpoints defined in the plugin.json manifest file located in the .claude-plugin directory, specifying URL paths, HTTP methods, parameters, and response schemas that Claude uses to interact with your service.

To define API endpoints for a Claude plugin, you must create a structured manifest that describes your plugin's HTTP interface according to the patterns established in the anthropics/claude-plugins-community repository. This manifest serves as the contract between your backend service and Claude, enabling the AI to discover available operations and construct valid requests automatically.

The Plugin Manifest Structure

Every Claude plugin requires a plugin.json file inside a hidden .claude-plugin directory at the repository root. This file declares the complete API specification, metadata, and authentication requirements that Claude needs to invoke your endpoints correctly.

Endpoint Configuration

Within .claude-plugin/plugin.json, define your API surface under the api key as an array of endpoint objects. Each endpoint must specify five critical properties:

  • url – The relative path Claude will call (e.g., /v1/transactions)
  • method – The HTTP verb (GET, POST, PUT, etc.)
  • description – A human-readable explanation of what the call accomplishes
  • parameters – An array of query-string or body parameters, each with name, type, required boolean, and description
  • response – A JSON schema describing the structure of successful responses

Authentication Setup

If your plugin requires credentials, include an auth object in the manifest. Claude automatically attaches the appropriate headers to every request based on this configuration. For Bearer token authentication, Claude injects Authorization: Bearer <token> using tokens supplied by users during plugin installation or via the Claude "API Keys" UI.

Implementing the Endpoint Handlers

While the manifest describes the interface contract, the actual business logic resides in your plugin's codebase. According to the repository structure, HTTP handlers live in skills/<skill-name>/scripts/ directories, with each skill corresponding to a functional unit declared in the manifest.

Example Handler Implementation

The following example matches the structure used in the tres-finance-plugin. First, define the endpoint in .claude-plugin/plugin.json:

{
  "name": "Transaction Creator",
  "version": "1.0.0",
  "description": "Create a new financial transaction in the Tres system.",
  "api": [
    {
      "url": "/v1/transactions",
      "method": "POST",
      "description": "Creates a new transaction record.",
      "parameters": [
        {
          "name": "amount",
          "type": "number",
          "required": true,
          "description": "The monetary amount of the transaction."
        },
        {
          "name": "currency",
          "type": "string",
          "required": true,
          "description": "Three‑letter ISO currency code (e.g., USD)."
        },
        {
          "name": "memo",
          "type": "string",
          "required": false,
          "description": "Optional free‑form description."
        }
      ],
      "response": {
        "type": "object",
        "properties": {
          "transactionId": { "type": "string" },
          "status": { "type": "string" }
        },
        "required": ["transactionId", "status"]
      }
    }
  ],
  "auth": {
    "type": "bearer",
    "header": "Authorization"
  }
}

Then implement the corresponding handler in skills/transaction-creator/scripts/app.py:

from flask import Blueprint, request, jsonify

router = Blueprint('transactions', __name__)

@router.post('/v1/transactions')
def create_transaction():
    data = request.json
    # Validate required fields

    amount = data.get('amount')
    currency = data.get('currency')
    memo = data.get('memo', '')

    # Business logic – create the transaction in the backend

    transaction_id = backend.create_transaction(amount, currency, memo)

    return jsonify({
        "transactionId": transaction_id,
        "status": "created"
    }), 201

Versioning and Schema Validation

The anthropics/claude-plugins-community repository enforces strict validation through .github/workflows/validate-plugins.yml. This CI workflow automatically verifies that:

  • All JSON schemas in plugin.json are syntactically valid
  • Every endpoint declared in the manifest has a corresponding handler in the codebase
  • breaking changes are properly indicated through semantic versioning

Always version your endpoints using URL prefixes (e.g., /v1/transactions) and update the version field in plugin.json when introducing breaking changes to maintain backward compatibility.

Testing Your Endpoints

Each skill must include integration tests in a skills/<skill-name>/tests/ directory. These tests use the same schema definitions found in plugin.json, ensuring the live implementation stays synchronized with the manifest contract. For example, the tres-finance-plugin includes tests like run_report_matrix.py that validate endpoint behavior against the declared response schemas before deployment.

Summary

  • Define API endpoints in .claude-plugin/plugin.json using the api array structure to declare your plugin's capabilities
  • Specify url, method, description, parameters, and response schema for each endpoint to enable Claude's automatic request construction
  • Implement handlers in skills/<skill-name>/scripts/ matching the exact paths and methods declared in your manifest
  • Configure authentication via the auth object to enable automatic header injection for secured endpoints
  • Version endpoints using URL prefixes (e.g., /v1/) and update the manifest version field when releasing breaking changes
  • Validate changes through the .github/workflows/validate-plugins.yml CI pipeline before submitting pull requests
  • Write integration tests in skills/<skill-name>/tests/ to verify that responses match the JSON schemas defined in your manifest

Frequently Asked Questions

What file format does Claude use for plugin API endpoint definitions?

Claude plugins use a JSON manifest located at .claude-plugin/plugin.json. This file follows a strict schema that defines the HTTP interface, including available endpoints, required parameters, response shapes, and authentication methods required for Claude to interact with your service.

How does Claude handle authentication for plugin API endpoints?

When you include an auth section in plugin.json, Claude automatically attaches the specified headers to every request. Users supply authentication tokens through the Claude interface during installation or via API Key settings, and Claude injects these credentials—such as Authorization: Bearer <token>—without exposing them in conversation logs.

Where should I implement the backend logic for my Claude plugin endpoints?

Implement HTTP handlers within the skills/<skill-name>/scripts/ directory structure, where each skill folder corresponds to a functional unit declared in your manifest. This modular organization ensures that endpoint implementations remain synchronized with their declarations and follow the repository's architectural conventions.

How does the repository validate that my endpoint definitions are correct?

The .github/workflows/validate-plugins.yml GitHub Actions workflow runs on every pull request to verify that all JSON schemas in your manifest are valid and that every referenced endpoint URL has a corresponding handler implementation in the codebase. This prevents deployment of plugins with broken or mismatched API contracts.

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 →