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 accomplishesparameters– An array of query-string or body parameters, each withname,type,requiredboolean, anddescriptionresponse– 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.jsonare 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.jsonusing theapiarray structure to declare your plugin's capabilities - Specify
url,method,description,parameters, andresponseschema 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
authobject to enable automatic header injection for secured endpoints - Version endpoints using URL prefixes (e.g.,
/v1/) and update the manifestversionfield when releasing breaking changes - Validate changes through the
.github/workflows/validate-plugins.ymlCI 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →