Skip to content

Commit f34a52d

Browse files
authored
Add task build (github#30)
* Add task build. * Update post-create instructions. * Update contributing doc.
1 parent 2e30e4f commit f34a52d

File tree

4 files changed

+119
-7
lines changed

4 files changed

+119
-7
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ task create -- --category database --image myorg/my-mcp https://github.com/myorg
130130
After creating your server file with `task create`, you will be given instructions for running it locally. In the case of my-orgdb-mcp, we would run the following commands next.
131131

132132
```
133+
task build -- my-orgdb-mcp # Not needed if providing your own image
133134
task catalog -- my-orgdb-mcp
134135
docker mcp catalog import $PWD/catalogs/my-orgdb-mcp/catalog.yaml
135136
```

Taskfile.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ tasks:
44
create:
55
desc: Create a new mcp server definition
66
cmd: go run ./cmd/create {{.CLI_ARGS}}
7+
8+
build:
9+
desc: Build a server image
10+
cmd: go run ./cmd/build {{.CLI_ARGS}}
711

812
catalog:
913
desc: Generate a test catalog

cmd/build/main.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
"fmt"
7+
"log"
8+
"os"
9+
"os/exec"
10+
"path/filepath"
11+
"strings"
12+
13+
"github.com/docker/mcp-registry/pkg/github"
14+
"github.com/docker/mcp-registry/pkg/servers"
15+
)
16+
17+
func main() {
18+
flag.Parse()
19+
args := flag.Args()
20+
21+
if len(args) != 1 {
22+
fmt.Println("Usage: task build -- <server>")
23+
os.Exit(1)
24+
}
25+
26+
if err := run(context.Background(), args[0]); err != nil {
27+
log.Fatal(err)
28+
}
29+
}
30+
31+
func run(ctx context.Context, name string) error {
32+
server, err := servers.Read(filepath.Join("servers", name, "server.yaml"))
33+
if err != nil {
34+
if os.IsNotExist(err) {
35+
return fmt.Errorf("server %s not found (did you already create it with `task create`?)", name)
36+
}
37+
return err
38+
}
39+
40+
if !strings.HasPrefix(server.Image, "mcp/") {
41+
return fmt.Errorf("server is not docker built (ie, in the 'mcp/' namespace), you must either build it yourself or pull it with `docker pull %s` if you want to use it", server.Image)
42+
}
43+
44+
projectURL := server.Source.Project
45+
branch := server.Source.Branch
46+
directory := server.Source.Directory
47+
48+
client := github.New()
49+
50+
repository, err := client.GetProjectRepository(ctx, projectURL)
51+
if err != nil {
52+
return err
53+
}
54+
55+
if branch == "" {
56+
branch = repository.GetDefaultBranch()
57+
}
58+
59+
sha, err := client.GetCommitSHA1(ctx, projectURL, branch)
60+
if err != nil {
61+
return err
62+
}
63+
64+
gitURL := projectURL + ".git#"
65+
if branch != "" {
66+
gitURL += branch
67+
}
68+
if directory != "" && directory != "." {
69+
gitURL += ":" + directory
70+
}
71+
72+
var cmd *exec.Cmd
73+
token := os.Getenv("GITHUB_TOKEN")
74+
75+
if token != "" {
76+
cmd = exec.CommandContext(ctx, "docker", "buildx", "build", "--secret", "id=GIT_AUTH_TOKEN", "-t", "check", "-t", server.Image, "--label", "org.opencontainers.image.revision="+sha, gitURL)
77+
cmd.Env = []string{"GIT_AUTH_TOKEN=" + token, "PATH=" + os.Getenv("PATH")}
78+
} else {
79+
cmd = exec.CommandContext(ctx, "docker", "buildx", "build", "-t", "check", "-t", server.Image, "--label", "org.opencontainers.image.revision="+sha, gitURL)
80+
cmd.Env = []string{"PATH=" + os.Getenv("PATH")}
81+
}
82+
83+
cmd.Dir = os.TempDir()
84+
cmd.Stdout = os.Stdout
85+
cmd.Stderr = os.Stderr
86+
87+
if err := cmd.Run(); err != nil {
88+
return err
89+
}
90+
91+
fmt.Println("✅ Image built as", server.Image)
92+
93+
return nil
94+
}

cmd/create/main.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -271,26 +271,39 @@ func run(ctx context.Context, buildURL, name, category, userProvidedImage string
271271

272272
fmt.Printf("Server definition written to %s.\n", serverFile)
273273

274-
fmt.Printf(`
275-
-----------------------------------------
276-
277-
What to do next?
274+
// Default to mcp build instructions
275+
step2 := fmt.Sprintf(`
276+
2. Test out your server in Docker Desktop building the image, generating a catalog, and importing it:
278277
279-
1. Review %[2]s and make sure no TODO remains.
278+
task build -- %[1]s
279+
task catalog -- %[1]s
280+
docker mcp catalog import $PWD/catalogs/%[1]s/catalog.yaml
281+
`, name)
280282

283+
if userProvidedImage != "" {
284+
step2 = fmt.Sprintf(`
281285
2. Test out your server in Docker Desktop by generating a catalog and importing it:
282286
283287
task catalog -- %[1]s
284288
docker mcp catalog import $PWD/catalogs/%[1]s/catalog.yaml
289+
`, name)
290+
}
291+
292+
fmt.Printf(`
293+
-----------------------------------------
285294
286-
3. After doing so, you should be able to test it with the MCP Toolkit.
295+
What to do next?
296+
297+
1. Review %[2]s and make sure no TODO remains.
298+
%[3]s
299+
3. After doing so, you should be able to test it with the MCP Toolkit. Repeat step 2 as needed while making changes.
287300
288301
4. Reset your catalog after testing:
289302
290303
docker mcp catalog reset
291304
292305
5. Open a Pull Request with the %[2]s file.
293-
`, name, serverFile)
306+
`, name, serverFile, step2)
294307

295308
return nil
296309
}

0 commit comments

Comments
 (0)