Skip to content

Commit 6a284c1

Browse files
authored
Support file:// schema when adding servers (#326)
* Support file:// schema for adding servers. * chore: recognize .yml extension on file import/export. * Lint fixes.
1 parent 989c5dc commit 6a284c1

13 files changed

Lines changed: 932 additions & 12 deletions

File tree

pkg/catalog/types.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ type topLevel struct {
1515
// MCP Servers
1616

1717
type Server struct {
18-
Name string `yaml:"name,omitempty" json:"name,omitempty"`
19-
Type string `yaml:"type" json:"type"`
18+
Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"required,min=1"`
19+
Type string `yaml:"type" json:"type" validate:"required,oneof=server remote poci"`
2020
Image string `yaml:"image" json:"image"`
2121
Description string `yaml:"description,omitempty" json:"description,omitempty"`
2222
Title string `yaml:"title,omitempty" json:"title,omitempty"`
@@ -33,7 +33,7 @@ type Server struct {
3333
DisableNetwork bool `yaml:"disableNetwork,omitempty" json:"disableNetwork,omitempty"`
3434
AllowHosts []string `yaml:"allowHosts,omitempty" json:"allowHosts,omitempty"`
3535
ExtraHosts []string `yaml:"extraHosts,omitempty" json:"extraHosts,omitempty"`
36-
Tools []Tool `yaml:"tools,omitempty" json:"tools,omitempty"`
36+
Tools []Tool `yaml:"tools,omitempty" json:"tools,omitempty" validate:"dive"`
3737
Config []any `yaml:"config,omitempty" json:"config,omitempty"`
3838
Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty"`
3939
Metadata *Metadata `yaml:"metadata,omitempty" json:"metadata,omitempty"`
@@ -107,7 +107,7 @@ type ToolGroup struct {
107107
}
108108

109109
type Tool struct {
110-
Name string `yaml:"name" json:"name"`
110+
Name string `yaml:"name" json:"name" validate:"required,min=1"`
111111
Description string `yaml:"description" json:"description"`
112112
Container Container `yaml:"container" json:"container"`
113113
Parameters Parameters `yaml:"parameters" json:"parameters"`

pkg/catalog_next/catalog.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,19 @@ func (catalog *Catalog) Validate() error {
138138
if err := validate.Get().Struct(catalog); err != nil {
139139
return err
140140
}
141-
return catalog.validateUniqueServerNames()
141+
if err := catalog.validateUniqueServerNames(); err != nil {
142+
return err
143+
}
144+
return catalog.validateServerSnapshots()
145+
}
146+
147+
func (catalog *Catalog) validateServerSnapshots() error {
148+
for _, server := range catalog.Servers {
149+
if err := server.Snapshot.ValidateInnerConfig(); err != nil {
150+
return err
151+
}
152+
}
153+
return nil
142154
}
143155

144156
func (catalog *Catalog) validateUniqueServerNames() error {

pkg/catalog_next/create_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ func TestCreateFromWorkingSetWithSnapshot(t *testing.T) {
211211
Server: catalog.Server{
212212
Name: "test-server",
213213
Description: "Test server",
214+
Type: "server",
215+
Image: "docker/test:latest",
214216
},
215217
}
216218

pkg/workingset/create_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ func getMockOciService() oci.Service {
1818
{
1919
Ref: "myimage:latest",
2020
Labels: map[string]string{
21-
"io.docker.server.metadata": "name: My Image",
21+
"io.docker.server.metadata": "name: My Image\ntype: server\nimage: myimage:latest",
2222
},
2323
DigestString: "sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
2424
},
2525
{
2626
Ref: "anotherimage:v1.0",
2727
Labels: map[string]string{
28-
"io.docker.server.metadata": "name: Another Image",
28+
"io.docker.server.metadata": "name: Another Image\ntype: server\nimage: anotherimage:v1.0",
2929
},
3030
DigestString: "sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
3131
},

pkg/workingset/export.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func Export(ctx context.Context, dao db.DAO, id string, filename string) error {
2626
workingSet := NewFromDb(dbSet)
2727

2828
var data []byte
29-
if strings.HasSuffix(strings.ToLower(filename), ".yaml") {
29+
if strings.HasSuffix(strings.ToLower(filename), ".yaml") || strings.HasSuffix(strings.ToLower(filename), ".yml") {
3030
data, err = yaml.Marshal(workingSet)
3131
} else if strings.HasSuffix(strings.ToLower(filename), ".json") {
3232
data, err = json.MarshalIndent(workingSet, "", " ")

pkg/workingset/import.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func Import(ctx context.Context, dao db.DAO, ociService oci.Service, filename st
2222
}
2323

2424
var workingSet WorkingSet
25-
if strings.HasSuffix(strings.ToLower(filename), ".yaml") {
25+
if strings.HasSuffix(strings.ToLower(filename), ".yaml") || strings.HasSuffix(strings.ToLower(filename), ".yml") {
2626
if err := yaml.Unmarshal(workingSetBuf, &workingSet); err != nil {
2727
return fmt.Errorf("failed to unmarshal profile: %w", err)
2828
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: my-mcp
2+
title: My MCP
3+
type: invalid
4+
image: myimage:latest
5+
description: Server that runs my MCP code
6+
env:
7+
- name: MODE
8+
value: "{{my-mcp.mode}}"
9+
secrets:
10+
- name: my-mcp.SECRET_KEY
11+
env: SECRET_KEY
12+
config:
13+
- name: my-mcp
14+
description: The configuration for the mcp server
15+
type: object
16+
properties:
17+
mode:
18+
type: string
19+
required:
20+
- mode
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
invalid: yaml: [syntax
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
version: 2
2+
name: my-mcp-catalog
3+
displayName: My MCP Catalog
4+
registry:
5+
my-mcp:
6+
title: My MCP
7+
type: server
8+
image: myimage:latest
9+
description: Server that runs my MCP code
10+
env:
11+
- name: MODE
12+
value: "{{my-mcp.mode}}"
13+
secrets:
14+
- name: my-mcp.SECRET_KEY
15+
env: SECRET_KEY
16+
config:
17+
- name: my-mcp
18+
description: The configuration for the mcp server
19+
type: object
20+
properties:
21+
mode:
22+
type: string
23+
required:
24+
- mode
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "my-mcp",
3+
"title": "My MCP",
4+
"type": "server",
5+
"image": "myimage:latest",
6+
"description": "Server that runs my MCP code",
7+
"env": [{
8+
"name": "MODE",
9+
"value": "{{my-mcp.mode}}"
10+
}],
11+
"secrets": [{
12+
"name": "my-mcp.SECRET_KEY",
13+
"env": "SECRET_KEY"
14+
}],
15+
"config": [
16+
{
17+
"name": "my-mcp",
18+
"description": "The configuration for the mcp server",
19+
"type": "object",
20+
"properties": {
21+
"mode": {
22+
"type": "string"
23+
}
24+
},
25+
"required": ["mode"]
26+
}
27+
]
28+
}

0 commit comments

Comments
 (0)