feat: implement server publishing endpoint with Bearer token authentication and update documentation

This commit is contained in:
Avinash Sridhar 2025-04-30 12:34:00 -04:00 • committed by Toby Padilla
commit 9c6eebbed0
2 changed files with 190 additions and 48 deletions

View file

@ -31,6 +31,7 @@ The compiled binary will be placed in the `bin` directory.
- `--registry-url`: URL of the MCP registry (required)
- `--mcp-file`: Path to the MCP configuration file (required)
- `--login`: Force a new GitHub authentication even if a token already exists (overwrites existing token file)
- `--token`: Use the provided token instead of GitHub authentication (bypasses the device flow)
## Authentication
@ -38,6 +39,7 @@ The tool uses GitHub device flow authentication:
1. When first run (or with `--login` flag), the tool will initiate the GitHub device flow
2. You'll be provided with a URL and a code to enter
3. After successful authentication, the tool saves the token locally for future use
4. The token is sent in the HTTP Authorization header with the Bearer scheme
_NOTE_ : Authentication is made on behalf of a OAuth App which you must authorize for respective resources (e.g `org`)

View file

@ -44,10 +44,12 @@ func main() {
var registryURL string
var mcpFilePath string
var forceLogin bool
var providedToken string
flag.StringVar(&registryURL, "registry-url", "", "URL of the registry(required)")
flag.StringVar(&mcpFilePath, "mcp-file", "", "path to the MCP file(required)")
flag.BoolVar(&forceLogin, "login", false, "force a new login even if a token exists")
flag.StringVar(&providedToken, "token", "", "use the provided token instead of GitHub authentication")
flag.Parse()
@ -56,23 +58,31 @@ func main() {
return
}
// Check if token exists or force login is requested
_, statErr := os.Stat(tokenFilePath)
if forceLogin || os.IsNotExist(statErr) {
err := performDeviceFlowLogin()
var token string
// If a token is provided via the command line, use it
if providedToken != "" {
token = providedToken
} else {
// Check if token exists or force login is requested
_, statErr := os.Stat(tokenFilePath)
if forceLogin || os.IsNotExist(statErr) {
err := performDeviceFlowLogin()
if err != nil {
fmt.Printf("Failed to perform device flow login: %s\n", err.Error())
return
}
}
// Read the token from the file
var err error
token, err = readToken()
if err != nil {
fmt.Printf("Failed to perform device flow login: %s\n", err.Error())
fmt.Printf("Error reading token: %s\n", err.Error())
return
}
}
// Read the token
token, err := readToken()
if err != nil {
fmt.Printf("Error reading token: %s\n", err.Error())
return
}
// Read MCP file
mcpData, err := os.ReadFile(mcpFilePath)
if err != nil {
@ -255,13 +265,9 @@ func publishToRegistry(registryURL string, mcpData []byte, token string) error {
return fmt.Errorf("error parsing mcp.json file: %w", err)
}
// Create the publish request payload
// Create the publish request payload (without authentication)
publishReq := map[string]interface{}{
"server_detail": mcpDetails,
"authentication": map[string]interface{}{
"method": "github",
"token": token,
},
}
// Convert the request to JSON
@ -282,6 +288,7 @@ func publishToRegistry(registryURL string, mcpData []byte, token string) error {
return fmt.Errorf("error creating request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+token)
client := &http.Client{}
resp, err := client.Do(req)