How the `sourceUrl` Shape Works in Claude Plugin Manifests

The sourceUrl field in a Claude plugin manifest accepts either a static URL string or a templated object with variable substitution to dynamically construct API endpoints at runtime.

The sourceUrl shape defines how Claude plugins connect to external APIs, specified in the .claude-plugin/plugin.json manifest. In the anthropics/claude-plugins-community repository, this field determines whether a plugin calls a fixed endpoint or generates dynamic URLs based on conversation context.

Anatomy of the sourceUrl Field

The sourceUrl property supports two distinct formats: a simple string for static endpoints or a structured object for dynamic templating.

Static URL String Format

When sourceUrl is a plain string, the plugin always calls that exact endpoint. This is suitable for APIs that do not require path parameters or dynamic query strings.

{
  "sourceUrl": "https://api.example.com/v1/status"
}

Templated Object Structure

When sourceUrl is an object, it uses a declarative template system with the following properties:

  • format (string): A URL template using {{variable}} syntax, such as https://api.example.com/v1/{{resource}}/{{id}}
  • variables (array of strings): The names of variables that must be supplied when rendering the template
  • method (string, optional): HTTP method to use (GET, POST, PUT, DELETE). Defaults to GET when omitted
  • headers (object, optional): Static headers to include on every request; dynamic headers can use variable placeholders within values
{
  "sourceUrl": {
    "format": "https://api.openweathermap.org/data/2.5/weather?q={{city}}&appid={{apiKey}}",
    "variables": ["city", "apiKey"],
    "method": "GET"
  }
}

Runtime Resolution Process

According to the anthropics/claude-plugins-community source implementation, the Claude runtime processes sourceUrl through four distinct stages:

  1. Parsing – The runtime loads the plugin manifest from .claude-plugin/plugin.json and identifies the sourceUrl entry
  2. Variable Resolution – Placeholders in the format string are replaced with values from the current conversation context or user input
  3. Request Construction – The final URL, HTTP method, and headers are assembled into a request object
  4. Execution – The request is dispatched to the external service, and the JSON response is returned to the model

This declarative approach allows the same plugin code to handle multiple endpoint variations without custom request-building logic.

Implementation Examples from anthropics/claude-plugins-community

The community repository demonstrates both static and dynamic sourceUrl configurations across multiple plugins:

These manifests illustrate how different plugins leverage the sourceUrl shape to connect to their respective backend services, whether using fixed endpoints or parameterized templates.

Complete Configuration Example

The following manifest shows a comprehensive sourceUrl configuration using dynamic variables and custom headers:

{
  "name": "WeatherPlugin",
  "description": "Fetches weather data for a city.",
  "sourceUrl": {
    "format": "https://api.weather.com/v1/{{location}}?units={{units}}",
    "variables": ["location", "units"],
    "method": "GET",
    "headers": {
      "Authorization": "Bearer {{token}}",
      "Content-Type": "application/json"
    }
  }
}

At runtime, with location="Paris", units="metric", and token="abcd1234", the resolved request becomes:


GET https://api.weather.com/v1/Paris?units=metric
Authorization: Bearer abcd1234
Content-Type: application/json

Summary

  • The sourceUrl field in .claude-plugin/plugin.json accepts either a static string or a templated object
  • Templated objects use {{variable}} syntax in the format field, with variable names declared in the variables array
  • The HTTP method defaults to GET but can be explicitly set to POST, PUT, or DELETE
  • Headers can be defined statically or dynamically using the same variable substitution mechanism
  • Runtime resolution occurs in four phases: parsing, variable resolution, request construction, and execution

Frequently Asked Questions

Can sourceUrl reference local files instead of HTTP endpoints?

No, the sourceUrl shape is specifically designed for HTTP and HTTPS endpoints. The field expects a URL format suitable for web requests, and the Claude runtime does not use this field to access local filesystem paths. Local file access within the repository is handled through other mechanisms, while sourceUrl defines external API integration points.

What happens if a required variable is missing at runtime?

If the conversation context does not provide a value for a variable listed in the variables array, the template cannot be fully resolved. The runtime typically fails the request construction phase, preventing the plugin call from executing. Plugin authors should ensure that all variables declared in the manifest are either provided by the user or handled with default values in the conversation flow.

Does the sourceUrl shape support authentication headers?

Yes, the headers object within a templated sourceUrl supports both static and dynamic authentication values. You can declare headers with static strings or use the {{variable}} syntax within header values to inject tokens, API keys, or session IDs supplied at runtime. This allows secure credential handling without hardcoding sensitive values in the manifest file.

Where is the sourceUrl field located within the plugin structure?

The sourceUrl field is defined in the main manifest file located at .claude-plugin/plugin.json in the plugin's root directory. This file serves as the entry point that Claude reads to understand the plugin's capabilities, description, and external API configuration. Each plugin subdirectory in the anthropics/claude-plugins-community repository contains this file to register its specific endpoint requirements.

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 →