How to Specify the Domain for Your Claude Plugin: Complete Manifest Guide
Add the domain or domains field to your plugin's JSON manifest file to declare which web host(s) your Claude plugin is authorized to access.
Claude plugins in the anthropics/claude-plugins-community repository use a JSON manifest to define their capabilities. The domain field—along with its plural variant domains—enables automatic routing, security validation, and marketplace discoverability. This guide explains how to configure domains correctly based on the official plugin specification and validation logic in the community repository.
Understanding the Domain Field in Claude Plugin Manifests
The domain declaration resides in your plugin's manifest, which is indexed by the marketplace at [.claude-plugin/marketplace.json](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json). This field serves three critical functions:
- Domain-based routing — Claude automatically invokes your plugin when users mention URLs from registered domains.
- Security enforcement — The validation CI (
.github/actions/validate-plugins) ensures declared domains resolve correctly and that plugins cannot access unregistered hosts. - User transparency — Claude surfaces the domain name in responses so users confirm they're using the intended service.
Single Domain vs. Multiple Domains
Use domain for one host and domains for multiple hosts:
| Field | Type | Use Case |
|---|---|---|
domain |
string |
Single host (e.g., "api.example.com") |
domains |
array[string] |
Multiple hosts (e.g., ["api.example.com", "dashboard.example.com"]) |
How to Add a Domain to Your Plugin Manifest
Step 1: Create or Edit Your Manifest File
Every Claude plugin requires a manifest entry in the marketplace index. Locate your plugin's definition in .claude-plugin/marketplace.json or create a new entry following the Claude Code plugin specification.
Step 2: Add the Domain Field
Insert domain or domains at the top level of your manifest object:
{
"name": "my-awesome-plugin",
"version": "0.1.0",
"description": "A plugin that talks to MyAwesomeService.",
"domain": "myawesome.service.com",
"entrypoint": "plugin_handler.py",
"commands": {
"fetch-data": {
"description": "Retrieve data from the service."
}
}
}
For multiple domains, use the array format:
{
"name": "multi-service-plugin",
"version": "1.2.0",
"description": "Integrates with multiple ProjectHQ services.",
"domains": ["api.projecthq.com", "app.projecthq.com", "cdn.projecthq.com"],
"entrypoint": "handler.js",
"commands": {
"list-projects": { "description": "List all projects." }
}
}
Step 3: Validate Your Domain Declaration
The marketplace CI at .github/actions/validate-plugins automatically checks that:
- Domain strings are well-formed hostnames.
- Declared domains resolve to reachable hosts.
- No conflicting domain claims exist between plugins.
Run local validation before submitting to catch errors early.
Complete Domain Specification Examples
Minimal Single-Domain Plugin
{
"name": "weather-fetcher",
"version": "0.2.1",
"description": "Fetches current weather from weather.example.com.",
"domain": "weather.example.com",
"entrypoint": "weather_fetcher.py",
"commands": {
"get-weather": {
"description": "Return weather for a city."
}
}
}
Multi-Domain Integration Plugin
{
"name": "project-tracker",
"version": "1.0.0",
"description": "Integrates with both the API and UI of ProjectHQ.",
"domains": ["api.projecthq.com", "app.projecthq.com"],
"entrypoint": "tracker.js",
"commands": {
"list-tasks": { "description": "List open tasks." },
"create-task": { "description": "Create a new task." }
}
}
Enforcing Domain Restrictions in Plugin Code
After specifying domains in the manifest, validate URLs at runtime to prevent unauthorized requests:
# skill.py
import urllib.parse
def resolve_domain(url, manifest):
"""Verify the requested URL matches declared plugin domains."""
host = urllib.parse.urlparse(url).hostname
# Collect allowed domains from manifest
allowed = manifest.get("domains", [manifest.get("domain")])
allowed = [d for d in allowed if d] # Filter out None
if host not in allowed:
raise ValueError(f"Unsupported domain: {host}. Allowed: {allowed}")
# Proceed with validated request
return make_request_to(url)
This pattern mirrors domain handling in example skills like [tres-finance-plugin/skills/tres-ledger-link/SKILL.md](https://github.com/anthropics/claude-plugins-community), which references sub-domains (<org-subdomain>.tres.finance) for organization-scoped access.
Domain Routing and Request Handling
When Claude processes a user message containing a URL, the system:
- Extracts the hostname from the URL (e.g.,
dashboard.example.comfromhttps://dashboard.example.com/report). - Matches against registered domains in all plugin manifests.
- Routes to the matching plugin if exactly one match exists, or prompts for clarification if multiple plugins claim the same domain.
Plugins without domain declarations remain invocable only by explicit command name, not URL mention.
Security and Marketplace Validation
The anthropics/claude-plugins-community repository enforces domain hygiene through automated checks:
- Resolution verification — Domains must resolve to valid DNS records.
- Reachability testing — Hosts must respond to HTTP requests.
- Conflict detection — No two plugins may claim identical domains without explicit namespacing.
Review the validation logic in [.github/actions/validate-plugins/README.md](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/README.md) for specifics on CI requirements.
Summary
- Add
domain(string) ordomains(array) to your plugin manifest to declare authorized hosts. - Domain declarations enable automatic URL routing, security enforcement, and marketplace discoverability.
- The marketplace CI validates that domains resolve correctly and don't conflict with other plugins.
- Runtime code should verify requested URLs against declared domains for defense in depth.
Key files to reference: [.claude-plugin/marketplace.json](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/marketplace.json) for manifest structure, and example skills in the repository for domain handling patterns.
Frequently Asked Questions
What happens if I don't specify a domain in my plugin manifest?
Claude can only invoke your plugin by explicit command name. Without a domain declaration, users cannot trigger your plugin by mentioning URLs, and the plugin won't appear in domain-based marketplace searches. Security checks still apply, but routing automation is unavailable.
Can I use wildcards or patterns in domain declarations?
No. According to the current specification in anthropics/claude-plugins-community, domains must be exact host strings. For sub-domain support, list each host explicitly in the domains array (e.g., ["us.api.example.com", "eu.api.example.com"]). Example skills demonstrate organization-scoped access via templated sub-domains handled in code, not manifest patterns.
How do I update my plugin's domain after publication?
Submit a pull request modifying your manifest entry in .claude-plugin/marketplace.json. The validation CI will re-check domain resolution and conflict status. If you're removing a previously declared domain, ensure no existing users depend on URL-based routing to that host, as the change may break their workflows.
Why does my plugin fail validation with "domain unreachable"?
The .github/actions/validate-plugins CI requires declared domains to resolve to reachable hosts. Common causes include: DNS propagation delays, firewall rules blocking automation, or typos in the hostname. Verify with dig or nslookup, ensure HTTP/HTTPS ports respond, and re-trigger the CI check after fixing infrastructure issues.
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 →