diff --git a/tools/publisher/README.md b/tools/publisher/README.md index c8b45cb..d13ee81 100644 --- a/tools/publisher/README.md +++ b/tools/publisher/README.md @@ -41,6 +41,16 @@ The tool uses GitHub device flow authentication: 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 +### Required Environment Variable + +Before using the GitHub authentication, you need to set the following environment variable: + +```bash +export MCP_REGISTRY_GITHUB_CLIENT_ID="your_github_client_id" +``` + +This environment variable is required for the GitHub device flow authentication. If not set, the authentication will fail. + _NOTE_ : Authentication is made on behalf of a OAuth App which you must authorize for respective resources (e.g `org`) ## Example @@ -91,6 +101,10 @@ _NOTE_ : Authentication is made on behalf of a OAuth App which you must authoriz 2. Run the publisher tool: ```bash +# First, set the required environment variable +export MCP_REGISTRY_GITHUB_CLIENT_ID="your_github_client_id" + +# Then run the publisher tool ./bin/mcp-publisher --registry-url "https://mcp-registry.example.com" --mcp-file "./mcp.json" ``` @@ -100,6 +114,7 @@ _NOTE_ : Authentication is made on behalf of a OAuth App which you must authoriz ## Important Notes +- The `MCP_REGISTRY_GITHUB_CLIENT_ID` environment variable must be set for GitHub authentication - The authentication token is saved in a file named `.mcpregistry_token` in the current directory - The tool requires an active internet connection to authenticate with GitHub and communicate with the registry - Make sure the repository and package mentioned in your `mcp.json` file exist and are accessible diff --git a/tools/publisher/main.go b/tools/publisher/main.go index db77484..80b006a 100644 --- a/tools/publisher/main.go +++ b/tools/publisher/main.go @@ -15,12 +15,12 @@ import ( const ( tokenFilePath = ".mcpregistry_token" - // TODO: Replace this with the official owned OAuth client ID - GithubClientID = "Ov23ct0x1531TPL3WJ9h" - // GitHub OAuth URLs GitHubDeviceCodeURL = "https://github.com/login/device/code" GitHubAccessTokenURL = "https://github.com/login/oauth/access_token" + + // Environment variable for GitHub Client ID + EnvGithubClientID = "MCP_REGISTRY_GITHUB_CLIENT_ID" ) // DeviceCodeResponse represents the response from GitHub's device code endpoint @@ -58,6 +58,19 @@ func main() { return } + // Check for GitHub client ID in environment if we're going to need it for authentication + if providedToken == "" && os.Getenv(EnvGithubClientID) == "" { + fmt.Printf("Warning: Environment variable %s is not set. This is required for GitHub authentication.\n", EnvGithubClientID) + fmt.Println("You can set it with: export " + EnvGithubClientID + "=your_github_client_id") + fmt.Println("Or provide a token directly with the --token flag.") + + // Only return if we'll need to do GitHub auth + _, statErr := os.Stat(tokenFilePath) + if forceLogin || os.IsNotExist(statErr) { + return + } + } + var token string // If a token is provided via the command line, use it @@ -101,6 +114,11 @@ func main() { } func performDeviceFlowLogin() error { + // Check if the environment variable is set + if os.Getenv(EnvGithubClientID) == "" { + return fmt.Errorf("environment variable %s must be set for GitHub authentication", EnvGithubClientID) + } + // Device flow login logic using GitHub's device flow // First, request a device code deviceCode, userCode, verificationURI, err := requestDeviceCode() @@ -133,8 +151,13 @@ func performDeviceFlowLogin() error { // requestDeviceCode initiates the device authorization flow func requestDeviceCode() (string, string, string, error) { + clientID := os.Getenv(EnvGithubClientID) + if clientID == "" { + return "", "", "", fmt.Errorf("environment variable %s is not set", EnvGithubClientID) + } + payload := map[string]string{ - "client_id": GithubClientID, + "client_id": clientID, "scope": "read:org read:user", } @@ -177,8 +200,13 @@ func requestDeviceCode() (string, string, string, error) { // pollForToken polls for access token after user completes authorization func pollForToken(deviceCode string) (string, error) { + clientID := os.Getenv(EnvGithubClientID) + if clientID == "" { + return "", fmt.Errorf("environment variable %s is not set", EnvGithubClientID) + } + payload := map[string]string{ - "client_id": GithubClientID, + "client_id": clientID, "device_code": deviceCode, "grant_type": "urn:ietf:params:oauth:grant-type:device_code", }