From ca3da9045b2e7869227aa176afe1fda8acd29e72 Mon Sep 17 00:00:00 2001 From: Jim Clark Date: Wed, 10 Sep 2025 06:42:55 -0700 Subject: [PATCH] Output new ServerID after publishing (#359) When using `mcp-publisher publish ...`, output the new server `ID` if publishing is successful. ## Motivation and Context It's useful to know this during testing. It means that you don't have to go and search for the new server ID afterwards. Once we have the `v0/servers/{name}/{version}`, I think we could consider removing this again. ## How Has This Been Tested? I've been using this while I test publishing to locally running registries. ## Breaking Changes none ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [x] I have added appropriate error handling - [x] I have added or updated documentation as needed --- cmd/publisher/commands/publish.go | 27 ++++++++++++++++++--------- pkg/api/v0/types.go | 7 +++++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/cmd/publisher/commands/publish.go b/cmd/publisher/commands/publish.go index 7a33194..e99cf1f 100644 --- a/cmd/publisher/commands/publish.go +++ b/cmd/publisher/commands/publish.go @@ -65,26 +65,31 @@ func PublishCommand(args []string) error { // Publish to registry _, _ = fmt.Fprintf(os.Stdout, "Publishing to %s...\n", registryURL) - if err := publishToRegistry(registryURL, serverData, token); err != nil { + response, err := publishToRegistry(registryURL, serverData, token) + if err != nil { return fmt.Errorf("publish failed: %w", err) } _, _ = fmt.Fprintln(os.Stdout, "✓ Successfully published") + if serverID := response.GetID(); serverID != "" { + _, _ = fmt.Fprintf(os.Stdout, "✓ Server Id %s", serverID) + } + return nil } -func publishToRegistry(registryURL string, serverData []byte, token string) error { +func publishToRegistry(registryURL string, serverData []byte, token string) (*apiv0.ServerJSON, error) { // Parse the server JSON data var serverJSON apiv0.ServerJSON err := json.Unmarshal(serverData, &serverJSON) if err != nil { - return fmt.Errorf("error parsing server.json file: %w", err) + return nil, fmt.Errorf("error parsing server.json file: %w", err) } // Convert to JSON jsonData, err := json.Marshal(serverJSON) if err != nil { - return fmt.Errorf("error serializing request: %w", err) + return nil, fmt.Errorf("error serializing request: %w", err) } // Ensure URL ends with the publish endpoint @@ -96,7 +101,7 @@ func publishToRegistry(registryURL string, serverData []byte, token string) erro // Create and send request req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, publishURL, bytes.NewBuffer(jsonData)) if err != nil { - return fmt.Errorf("error creating request: %w", err) + return nil, fmt.Errorf("error creating request: %w", err) } req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", "Bearer "+token) @@ -104,19 +109,23 @@ func publishToRegistry(registryURL string, serverData []byte, token string) erro client := &http.Client{} resp, err := client.Do(req) if err != nil { - return fmt.Errorf("error sending request: %w", err) + return nil, fmt.Errorf("error sending request: %w", err) } defer resp.Body.Close() // Read response body, err := io.ReadAll(resp.Body) if err != nil { - return fmt.Errorf("error reading response: %w", err) + return nil, fmt.Errorf("error reading response: %w", err) } if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusOK { - return fmt.Errorf("server returned status %d: %s", resp.StatusCode, body) + return nil, fmt.Errorf("server returned status %d: %s", resp.StatusCode, body) } - return nil + if err := json.Unmarshal(body, &serverJSON); err != nil { + return nil, err + } + + return &serverJSON, nil } diff --git a/pkg/api/v0/types.go b/pkg/api/v0/types.go index 41c7d42..e2cfce0 100644 --- a/pkg/api/v0/types.go +++ b/pkg/api/v0/types.go @@ -44,3 +44,10 @@ type Metadata struct { NextCursor string `json:"next_cursor,omitempty"` Count int `json:"count"` } + +func (s *ServerJSON) GetID() string { + if s.Meta != nil && s.Meta.Official != nil { + return s.Meta.Official.ID + } + return "" +}