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 <radoslav@stacklok.com>
This commit is contained in:
parent
7299960430
commit
a100367461
2 changed files with 26 additions and 2 deletions
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/modelcontextprotocol/registry/pkg/model"
|
"github.com/modelcontextprotocol/registry/pkg/model"
|
||||||
|
|
@ -42,8 +43,8 @@ func ValidateNPM(ctx context.Context, pkg model.Package, serverName string) erro
|
||||||
|
|
||||||
client := &http.Client{Timeout: 10 * time.Second}
|
client := &http.Client{Timeout: 10 * time.Second}
|
||||||
|
|
||||||
url := pkg.RegistryBaseURL + "/" + pkg.Identifier + "/" + pkg.Version
|
requestURL := pkg.RegistryBaseURL + "/" + url.PathEscape(pkg.Identifier) + "/" + url.PathEscape(pkg.Version)
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, requestURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create request: %w", err)
|
return fmt.Errorf("failed to create request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,29 @@ func TestValidateNPM_RealPackages(t *testing.T) {
|
||||||
serverName: "io.github.domdomegg/airtable-mcp-server",
|
serverName: "io.github.domdomegg/airtable-mcp-server",
|
||||||
expectError: false,
|
expectError: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "scoped package that doesn't exist should fail",
|
||||||
|
packageName: "@nonexistent-scope/nonexistent-package",
|
||||||
|
version: "1.0.0",
|
||||||
|
serverName: "com.example/test",
|
||||||
|
expectError: true,
|
||||||
|
errorMessage: "not found",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "scoped package without mcpName should fail",
|
||||||
|
packageName: "@types/node",
|
||||||
|
version: "20.0.0",
|
||||||
|
serverName: "com.example/test",
|
||||||
|
expectError: true,
|
||||||
|
errorMessage: "missing required 'mcpName' field",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "scoped package with mcpName should pass",
|
||||||
|
packageName: "@hellocoop/admin-mcp",
|
||||||
|
version: "1.5.7",
|
||||||
|
serverName: "io.github.hellocoop/admin-mcp",
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue