Skip to content

Commit a100367

Browse files
domdomeggrdimitrov
andauthored
Fix NPM package validation for scoped packages (#429)
## Summary - Add URL encoding for package identifiers and versions in NPM registry requests - Fixes issue where scoped packages like @hellocoop/admin-mcp failed validation due to unencoded @ and / symbols - Add unit tests for scoped NPM packages to prevent regression Fixes #409 Co-authored-by: Radoslav Dimitrov <[email protected]>
1 parent 7299960 commit a100367

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

internal/validators/registries/npm.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"fmt"
77
"net/http"
8+
"net/url"
89
"time"
910

1011
"github.com/modelcontextprotocol/registry/pkg/model"
@@ -42,8 +43,8 @@ func ValidateNPM(ctx context.Context, pkg model.Package, serverName string) erro
4243

4344
client := &http.Client{Timeout: 10 * time.Second}
4445

45-
url := pkg.RegistryBaseURL + "/" + pkg.Identifier + "/" + pkg.Version
46-
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
46+
requestURL := pkg.RegistryBaseURL + "/" + url.PathEscape(pkg.Identifier) + "/" + url.PathEscape(pkg.Version)
47+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)
4748
if err != nil {
4849
return fmt.Errorf("failed to create request: %w", err)
4950
}

internal/validators/registries/npm_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,29 @@ func TestValidateNPM_RealPackages(t *testing.T) {
9191
serverName: "io.github.domdomegg/airtable-mcp-server",
9292
expectError: false,
9393
},
94+
{
95+
name: "scoped package that doesn't exist should fail",
96+
packageName: "@nonexistent-scope/nonexistent-package",
97+
version: "1.0.0",
98+
serverName: "com.example/test",
99+
expectError: true,
100+
errorMessage: "not found",
101+
},
102+
{
103+
name: "scoped package without mcpName should fail",
104+
packageName: "@types/node",
105+
version: "20.0.0",
106+
serverName: "com.example/test",
107+
expectError: true,
108+
errorMessage: "missing required 'mcpName' field",
109+
},
110+
{
111+
name: "scoped package with mcpName should pass",
112+
packageName: "@hellocoop/admin-mcp",
113+
version: "1.5.7",
114+
serverName: "io.github.hellocoop/admin-mcp",
115+
expectError: false,
116+
},
94117
}
95118

96119
for _, tt := range tests {

0 commit comments

Comments
 (0)