Skip to content

Commit 1555c99

Browse files
tadasantclaude
andcommitted
feat: Implement clean variables object for remote URL templating
Replace array-based variables with an object where keys are variable names and values are Input definitions. This provides a much cleaner API and enables rich client UIs. Key improvements: - Variables as object: {"tenant_id": {"description": "...", "isRequired": true}} - No duplicate 'name' field - variable name is the object key - Full Input capabilities: choices, isSecret, default, format, etc. - Consistent with existing InputWithVariables pattern - Client-friendly for building rich UIs (dropdowns, validation, etc.) Example: { "url": "https://api.example.github.io/mcp/{tenant_id}", "variables": { "tenant_id": { "description": "Tenant identifier", "isRequired": true, "choices": ["us-cell1", "emea-cell1"] } } } All validation and tests pass. Schema, Go types, validators, and example have been updated to support the new structure. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 040fbec commit 1555c99

File tree

4 files changed

+21
-22
lines changed

4 files changed

+21
-22
lines changed

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -683,13 +683,12 @@ This example demonstrates URL templating for remote servers, useful for multi-te
683683
{
684684
"type": "streamable-http",
685685
"url": "https://api.example.github.io/mcp/{tenant_id}",
686-
"variables": [
687-
{
688-
"name": "tenant_id",
686+
"variables": {
687+
"tenant_id": {
689688
"description": "Tenant identifier (e.g., 'us-cell1', 'emea-cell1')",
690689
"isRequired": true
691690
}
692-
]
691+
}
693692
}
694693
]
695694
}

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

Lines changed: 10 additions & 10 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 variable names from the 'variables' array. If variables are not provided, {curly_braces} should be treated as literal text. After variable substitution, this should produce a valid URI.",
380+
"description": "URL template for the streamable-http transport. Variables in {curly_braces} reference variable names from the 'variables' object. If variables 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": {
@@ -388,10 +388,10 @@
388388
}
389389
},
390390
"variables": {
391-
"type": "array",
392-
"description": "Configuration variables that can be referenced in URL template {curly_braces} via their name property",
393-
"items": {
394-
"$ref": "#/definitions/KeyValueInput"
391+
"type": "object",
392+
"description": "Configuration variables that can be referenced in URL template {curly_braces}. The key is the variable name, and the value defines the variable properties.",
393+
"additionalProperties": {
394+
"$ref": "#/definitions/Input"
395395
}
396396
}
397397
}
@@ -414,7 +414,7 @@
414414
"url": {
415415
"type": "string",
416416
"format": "uri",
417-
"description": "Server-Sent Events endpoint URL template. Variables in {curly_braces} reference variable names from the 'variables' array. If variables are not provided, {curly_braces} should be treated as literal text. After variable substitution, this should produce a valid URI.",
417+
"description": "Server-Sent Events endpoint URL template. Variables in {curly_braces} reference variable names from the 'variables' object. If variables are not provided, {curly_braces} should be treated as literal text. After variable substitution, this should produce a valid URI.",
418418
"example": "https://mcp-fs.example.com/sse"
419419
},
420420
"headers": {
@@ -425,10 +425,10 @@
425425
}
426426
},
427427
"variables": {
428-
"type": "array",
429-
"description": "Configuration variables that can be referenced in URL template {curly_braces} via their name property",
430-
"items": {
431-
"$ref": "#/definitions/KeyValueInput"
428+
"type": "object",
429+
"description": "Configuration variables that can be referenced in URL template {curly_braces}. The key is the variable name, and the value defines the variable properties.",
430+
"additionalProperties": {
431+
"$ref": "#/definitions/Input"
432432
}
433433
}
434434
}

internal/validators/validators.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,10 @@ func collectAvailableVariables(pkg *model.Package) []string {
296296
func collectRemoteTransportVariables(transport *model.Transport) []string {
297297
var variables []string
298298

299-
// Add variable names from the Variables field
300-
for _, variable := range transport.Variables {
301-
if variable.Name != "" {
302-
variables = append(variables, variable.Name)
299+
// Add variable names from the Variables map
300+
for variableName := range transport.Variables {
301+
if variableName != "" {
302+
variables = append(variables, variableName)
303303
}
304304
}
305305

pkg/model/types.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ const (
1111

1212
// Transport represents transport configuration with optional URL templating
1313
type Transport struct {
14-
Type string `json:"type"`
15-
URL string `json:"url,omitempty"`
16-
Headers []KeyValueInput `json:"headers,omitempty"`
17-
Variables []KeyValueInput `json:"variables,omitempty"`
14+
Type string `json:"type"`
15+
URL string `json:"url,omitempty"`
16+
Headers []KeyValueInput `json:"headers,omitempty"`
17+
Variables map[string]Input `json:"variables,omitempty"`
1818
}
1919

2020
// Package represents a package configuration

0 commit comments

Comments
 (0)