--- title: Publishing Remote Servers sidebarTitle: Remote Servers --- The MCP Registry is currently in preview. Breaking changes or data resets may occur before general availability. If you encounter any issues, please report them on [GitHub](https://github.com/modelcontextprotocol/registry/issues). The MCP Registry supports remote MCP servers via the `remotes` property in `server.json`: ```json server.json highlight={7-12} { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", "name": "com.example/acme-analytics", "title": "ACME Analytics", "description": "Real-time business intelligence and reporting platform", "version": "2.0.0", "remotes": [ { "type": "streamable-http", "url": "https://analytics.example.com/mcp" } ] } ``` A remote server **MUST** be publicly accessible at its specified URL. A server with only `remotes` does not need a `packages` entry, so the package ownership verification described in [Package Types](./package-types) does not apply. ## Ownership Verification When you publish, the Registry verifies that you control the namespace in the server `name` using your [authentication method](./authentication). It does **not** verify that you control the remote URL, regardless of authentication method: - With [GitHub authentication](./authentication#github-authentication), a server named `io.github.my-username/weather` proves control of the `my-username` GitHub account, not of the domain serving the remote URL. - With [DNS authentication](./authentication#dns-authentication) or [HTTP authentication](./authentication#http-authentication), a server named `com.example/weather` proves control of `example.com`, but the Registry does not check that the remote URL is on `example.com`. If your remote URL is on a domain you control, consider using DNS or HTTP authentication so the server name reflects that domain. This lets users see that the server name and remote URL belong to the same publisher. Each remote URL can be used by only one server name. Publishing fails if another server already uses the same URL. ## Transport Type Remote servers should use the Streamable HTTP transport. The SSE transport is [deprecated](/specification/draft/deprecated), so publish an `"sse"` remote only to support existing clients. Remote servers can also support both transports simultaneously at different URLs. Specify the transport by setting the `type` property of the `remotes` entry to either `"streamable-http"` or `"sse"`: ```json server.json highlight={9,13} { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", "name": "com.example/acme-analytics", "title": "ACME Analytics", "description": "Real-time business intelligence and reporting platform", "version": "2.0.0", "remotes": [ { "type": "streamable-http", "url": "https://analytics.example.com/mcp" }, { "type": "sse", "url": "https://analytics.example.com/sse" } ] } ``` ## URL Template Variables Remote servers can define URL template variables using `{curly_braces}` notation. This enables multi-tenant deployments where a single server definition can support multiple endpoints with configurable values: ```json server.json highlight={10-17} { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", "name": "com.example/acme-analytics", "title": "ACME Analytics", "description": "Real-time business intelligence and reporting platform", "version": "2.0.0", "remotes": [ { "type": "streamable-http", "url": "https://{tenant_id}.analytics.example.com/mcp", "variables": { "tenant_id": { "description": "Your tenant identifier (e.g., 'us-cell1', 'emea-cell1')", "isRequired": true } } } ] } ``` When configuring this server, users provide their `tenant_id` value, and the URL template gets resolved to the appropriate endpoint (e.g., `https://us-cell1.analytics.example.com/mcp`). Variables support additional properties like `default`, `choices`, and `isSecret`: ```json server.json highlight={12-22} { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", "name": "com.example/multi-region-mcp", "title": "Multi-Region MCP", "description": "MCP server with regional endpoints", "version": "1.0.0", "remotes": [ { "type": "streamable-http", "url": "https://api.example.com/{region}/mcp", "variables": { "region": { "description": "Deployment region", "isRequired": true, "choices": [ "us-east-1", "eu-west-1", "ap-southeast-1" ], "default": "us-east-1" } } } ] } ``` ## HTTP Headers MCP clients can be instructed to send specific HTTP headers by adding the `headers` property to the `remotes` entry: ```json server.json highlight={11-18} { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", "name": "com.example/acme-analytics", "title": "ACME Analytics", "description": "Real-time business intelligence and reporting platform", "version": "2.0.0", "remotes": [ { "type": "streamable-http", "url": "https://analytics.example.com/mcp", "headers": [ { "name": "X-API-Key", "description": "API key for authentication", "isRequired": true, "isSecret": true } ] } ] } ``` ## Supporting Remote and Non-remote Installation The `remotes` property can coexist with the `packages` property in `server.json` in order to allow MCP host applications to choose the preferred method of installation. ```json server.json highlight={7-22} { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", "name": "io.github.username/email-integration-mcp", "title": "Email Integration", "description": "Send emails and manage email accounts", "version": "1.0.0", "remotes": [ { "type": "streamable-http", "url": "https://email.example.com/mcp" } ], "packages": [ { "registryType": "npm", "identifier": "@example/email-integration-mcp", "version": "1.0.0", "transport": { "type": "stdio" } } ] } ```