Skip to content

Commit 32140fa

Browse files
tadasantclaude
andcommitted
feat: Add template variable support for remote transport URLs
Enable URL templating for StreamableHttpTransport and SseTransport by adding 'arguments' and 'environmentVariables' arrays. This allows remote servers to support multi-tenant deployments with configurable endpoints. Key changes: - Add optional 'arguments' array to both transport types for valueHint-based templating - Add optional 'environmentVariables' array for environment-based templating - Update URL descriptions to clarify template variable resolution behavior - Add comprehensive multi-tenant example demonstrating the new functionality - Maintain backwards compatibility - existing configs continue to work This addresses the common use case where remote MCP servers are deployed across multiple tenants/regions, each requiring different endpoint URLs. Variables in {curly_braces} now properly resolve from the defined arrays. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 4962609 commit 32140fa

File tree

2 files changed

+127
-2
lines changed

2 files changed

+127
-2
lines changed

docs/reference/server-json/generic-server-json.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,103 @@ For MCP servers that follow a custom installation path or are embedded in applic
670670
}
671671
```
672672

673+
### Multi-Tenant Remote Server with URL Templating
674+
675+
This example demonstrates how to use URL templating for remote servers deployed across multiple tenants or regions, addressing scenarios where each deployment has its own endpoint:
676+
677+
```json
678+
{
679+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-16/server.schema.json",
680+
"name": "io.github.example/multi-tenant-analytics",
681+
"description": "Multi-tenant analytics MCP server with region-specific endpoints",
682+
"repository": {
683+
"url": "https://github.com/example/multi-tenant-analytics",
684+
"source": "github",
685+
"id": "tenant-abc123-def456-789012-345678-901234567890"
686+
},
687+
"version": "2.1.0",
688+
"remotes": [
689+
{
690+
"type": "streamable-http",
691+
"url": "https://{tenant_host}/api/ai/v1/mcp/",
692+
"headers": [
693+
{
694+
"name": "X-API-Key",
695+
"description": "API key for authentication",
696+
"isRequired": true,
697+
"isSecret": true
698+
},
699+
{
700+
"name": "X-Region",
701+
"value": "{deployment_region}",
702+
"description": "Deployment region identifier"
703+
}
704+
],
705+
"environmentVariables": [
706+
{
707+
"name": "TENANT_HOST",
708+
"description": "Tenant-specific hostname (e.g., 'us-cell1.example.com', 'emea-cell1.example.com')",
709+
"isRequired": true
710+
},
711+
{
712+
"name": "DEPLOYMENT_REGION",
713+
"description": "Deployment region code",
714+
"default": "us-east-1",
715+
"choices": [
716+
"us-east-1",
717+
"us-west-2",
718+
"eu-west-1",
719+
"ap-southeast-1"
720+
]
721+
}
722+
],
723+
"arguments": [
724+
{
725+
"type": "positional",
726+
"valueHint": "tenant_host",
727+
"description": "Override tenant host from environment",
728+
"isRequired": false
729+
},
730+
{
731+
"type": "positional",
732+
"valueHint": "deployment_region",
733+
"description": "Override deployment region from environment",
734+
"isRequired": false
735+
}
736+
]
737+
},
738+
{
739+
"type": "sse",
740+
"url": "https://{tenant_host}/api/ai/v1/mcp/events",
741+
"environmentVariables": [
742+
{
743+
"name": "TENANT_HOST",
744+
"description": "Tenant-specific hostname",
745+
"isRequired": true
746+
}
747+
]
748+
}
749+
],
750+
"_meta": {
751+
"io.modelcontextprotocol.registry/publisher-provided": {
752+
"tool": "multi-tenant-deployer",
753+
"version": "1.5.0",
754+
"build_info": {
755+
"timestamp": "2023-12-15T10:45:00Z",
756+
"supported_tenants": ["us-cell1", "us-cell2", "emea-cell1", "apac-cell1"],
757+
"deployment_strategy": "multi-region"
758+
}
759+
}
760+
}
761+
}
762+
```
763+
764+
This configuration allows clients to:
765+
- Set `TENANT_HOST=us-cell1.example.com` to connect to US Cell 1
766+
- Set `TENANT_HOST=emea-cell1.example.com` to connect to EMEA Cell 1
767+
- Specify the deployment region for proper routing
768+
- Use either streamable-http or SSE transports with the same tenant-specific endpoints
769+
673770
### Deprecated Server Example
674771

675772
```json

docs/reference/server-json/server.schema.json

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@
377377
},
378378
"url": {
379379
"type": "string",
380-
"description": "URL template for the streamable-http transport. Variables in {curly_braces} reference argument valueHints, argument names, or environment variable names. After variable substitution, this should produce a valid URI.",
380+
"description": "URL template for the streamable-http transport. Variables in {curly_braces} reference argument valueHints from 'arguments' array or names from 'environmentVariables' array. If arguments/environmentVariables are not provided, {curly_braces} should be treated as literal text. After variable substitution, this should produce a valid URI.",
381381
"example": "https://api.example.com/mcp"
382382
},
383383
"headers": {
@@ -386,6 +386,20 @@
386386
"items": {
387387
"$ref": "#/definitions/KeyValueInput"
388388
}
389+
},
390+
"arguments": {
391+
"type": "array",
392+
"description": "Arguments that can be referenced in URL template {curly_braces} via their valueHint property",
393+
"items": {
394+
"$ref": "#/definitions/Argument"
395+
}
396+
},
397+
"environmentVariables": {
398+
"type": "array",
399+
"description": "Environment variables that can be referenced in URL template {curly_braces} via their name property",
400+
"items": {
401+
"$ref": "#/definitions/KeyValueInput"
402+
}
389403
}
390404
}
391405
},
@@ -407,7 +421,7 @@
407421
"url": {
408422
"type": "string",
409423
"format": "uri",
410-
"description": "Server-Sent Events endpoint URL",
424+
"description": "Server-Sent Events endpoint URL template. Variables in {curly_braces} reference argument valueHints from 'arguments' array or names from 'environmentVariables' array. If arguments/environmentVariables are not provided, {curly_braces} should be treated as literal text. After variable substitution, this should produce a valid URI.",
411425
"example": "https://mcp-fs.example.com/sse"
412426
},
413427
"headers": {
@@ -416,6 +430,20 @@
416430
"items": {
417431
"$ref": "#/definitions/KeyValueInput"
418432
}
433+
},
434+
"arguments": {
435+
"type": "array",
436+
"description": "Arguments that can be referenced in URL template {curly_braces} via their valueHint property",
437+
"items": {
438+
"$ref": "#/definitions/Argument"
439+
}
440+
},
441+
"environmentVariables": {
442+
"type": "array",
443+
"description": "Environment variables that can be referenced in URL template {curly_braces} via their name property",
444+
"items": {
445+
"$ref": "#/definitions/KeyValueInput"
446+
}
419447
}
420448
}
421449
},

0 commit comments

Comments
 (0)