Skip to content

Commit 905fca0

Browse files
Copilotalexec
andauthored
Add arbitrary field support to MCP server configuration (#161)
* Initial plan * Add support for arbitrary fields in MCP server configuration Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Add example demonstrating arbitrary fields in MCP server config Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> * Add defensive initialization of Content map in UnmarshalJSON Co-authored-by: alexec <1142830+alexec@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: alexec <1142830+alexec@users.noreply.github.com>
1 parent 780008f commit 905fca0

3 files changed

Lines changed: 513 additions & 6 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
task_name: example-mcp-arbitrary-fields
3+
agent: cursor
4+
mcp_servers:
5+
# Example with standard fields only
6+
filesystem:
7+
type: stdio
8+
command: filesystem
9+
10+
# Example with standard fields plus arbitrary custom fields
11+
custom-database:
12+
type: stdio
13+
command: database-mcp
14+
args: ["--verbose"]
15+
# Arbitrary fields below
16+
cache_enabled: true
17+
max_cache_size: 1000
18+
connection_pool_size: 10
19+
20+
# Example HTTP server with custom metadata
21+
api-server:
22+
type: http
23+
url: https://api.example.com
24+
headers:
25+
Authorization: Bearer token123
26+
# Arbitrary fields below
27+
api_version: v2
28+
rate_limit: 100
29+
timeout_seconds: 30
30+
retry_policy: exponential
31+
region: us-west-2
32+
33+
# Example with nested custom configuration
34+
advanced-server:
35+
type: stdio
36+
command: python
37+
args: ["-m", "server"]
38+
env:
39+
PYTHON_PATH: /usr/bin/python3
40+
# Arbitrary nested fields below
41+
custom_config:
42+
host: localhost
43+
port: 5432
44+
ssl: true
45+
pool:
46+
min: 2
47+
max: 10
48+
monitoring:
49+
enabled: true
50+
metrics_port: 9090
51+
---
52+
53+
# Example Task with Arbitrary MCP Server Fields
54+
55+
This task demonstrates the ability to add arbitrary fields to MCP server configurations, just like we can with FrontMatter.
56+
57+
## Why Arbitrary Fields?
58+
59+
Different MCP servers may need different configuration options beyond the standard fields (`type`, `command`, `args`, `env`, `url`, `headers`). Arbitrary fields allow you to:
60+
61+
1. **Add custom metadata**: Version info, regions, endpoints, etc.
62+
2. **Configure behavior**: Caching, retry policies, timeouts, rate limits
63+
3. **Include nested config**: Complex configuration objects specific to your server
64+
4. **Future-proof**: Add new fields without changing the schema
65+
66+
## How It Works
67+
68+
The `MCPServerConfig` struct now includes a `Content` field (similar to `BaseFrontMatter`) that captures all fields from YAML/JSON:
69+
70+
```go
71+
type MCPServerConfig struct {
72+
// Standard fields
73+
Type TransportType
74+
Command string
75+
Args []string
76+
Env map[string]string
77+
URL string
78+
Headers map[string]string
79+
80+
// Arbitrary fields via inline map
81+
Content map[string]any `yaml:",inline"`
82+
}
83+
```
84+
85+
## Example Usage
86+
87+
The examples above show:
88+
- **Simple custom fields**: `cache_enabled`, `max_cache_size`
89+
- **API configuration**: `api_version`, `rate_limit`, `timeout_seconds`
90+
- **Nested objects**: `custom_config` with sub-fields like `host`, `port`, `ssl`
91+
- **Multiple custom sections**: `custom_config` and `monitoring` as separate objects
92+
93+
All these fields are preserved when the configuration is parsed and can be accessed via the `Content` map.

pkg/codingcontext/mcp_server_config.go

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,63 @@
11
package codingcontext
22

3+
import (
4+
"encoding/json"
5+
)
6+
37
// MCPServerConfig defines the common configuration fields supported by both platforms.
8+
// It also supports arbitrary additional fields via the Content map.
49
type MCPServerConfig struct {
510
// Type specifies the connection protocol.
611
// Values: "stdio", "sse", "http".
7-
Type TransportType `json:"type,omitempty"`
12+
Type TransportType `json:"type,omitempty" yaml:"type,omitempty"`
813

914
// Command is the executable to run (e.g. "npx", "docker").
1015
// Required for "stdio" type.
11-
Command string `json:"command,omitempty"`
16+
Command string `json:"command,omitempty" yaml:"command,omitempty"`
1217

1318
// Args is an array of arguments for the command.
14-
Args []string `json:"args,omitempty"`
19+
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
1520

1621
// Env defines environment variables for the server process.
17-
Env map[string]string `json:"env,omitempty"`
22+
Env map[string]string `json:"env,omitempty" yaml:"env,omitempty"`
1823

1924
// URL is the endpoint for "http" or "sse" types.
2025
// Required for remote connections.
21-
URL string `json:"url,omitempty"`
26+
URL string `json:"url,omitempty" yaml:"url,omitempty"`
2227

2328
// Headers contains custom HTTP headers (e.g. {"Authorization": "Bearer ..."}).
2429
// Used for "http" and "sse" types.
25-
Headers map[string]string `json:"headers,omitempty"`
30+
Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"`
31+
32+
// Content holds arbitrary additional fields from YAML/JSON that aren't in the struct
33+
Content map[string]any `json:"-" yaml:",inline"`
34+
}
35+
36+
// UnmarshalJSON custom unmarshaler that populates both typed fields and Content map
37+
func (m *MCPServerConfig) UnmarshalJSON(data []byte) error {
38+
// First unmarshal into a temporary type to avoid infinite recursion
39+
type Alias MCPServerConfig
40+
aux := &struct {
41+
*Alias
42+
}{
43+
Alias: (*Alias)(m),
44+
}
45+
46+
if err := json.Unmarshal(data, aux); err != nil {
47+
return err
48+
}
49+
50+
// Initialize Content map if needed
51+
if m.Content == nil {
52+
m.Content = make(map[string]any)
53+
}
54+
55+
// Also unmarshal into Content map
56+
if err := json.Unmarshal(data, &m.Content); err != nil {
57+
return err
58+
}
59+
60+
return nil
2661
}
2762

2863
// MCPServerConfigs maps server names to their configurations.

0 commit comments

Comments
 (0)