feat: require GitHub Client ID environment variable for publshing

This commit is contained in:
Avinash Sridhar 2025-05-06 11:37:21 -04:00 • committed by Toby Padilla
commit d32b528104
2 changed files with 48 additions and 5 deletions

View file

@ -41,6 +41,16 @@ The tool uses GitHub device flow authentication:
3. After successful authentication, the tool saves the token locally for future use 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 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`) _NOTE_ : Authentication is made on behalf of a OAuth App which you must authorize for respective resources (e.g `org`)
## Example ## Example
@ -91,6 +101,10 @@ _NOTE_ : Authentication is made on behalf of a OAuth App which you must authoriz
2. Run the publisher tool: 2. Run the publisher tool:
```bash ```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" ./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 ## 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 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 - 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 - Make sure the repository and package mentioned in your `mcp.json` file exist and are accessible

View file

@ -15,12 +15,12 @@ import (
const ( const (
tokenFilePath = ".mcpregistry_token" tokenFilePath = ".mcpregistry_token"
// TODO: Replace this with the official owned OAuth client ID
GithubClientID = "Ov23ct0x1531TPL3WJ9h"
// GitHub OAuth URLs // GitHub OAuth URLs
GitHubDeviceCodeURL = "https://github.com/login/device/code" GitHubDeviceCodeURL = "https://github.com/login/device/code"
GitHubAccessTokenURL = "https://github.com/login/oauth/access_token" 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 // DeviceCodeResponse represents the response from GitHub's device code endpoint
@ -58,6 +58,19 @@ func main() {
return 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 var token string
// If a token is provided via the command line, use it // If a token is provided via the command line, use it
@ -101,6 +114,11 @@ func main() {
} }
func performDeviceFlowLogin() error { 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 // Device flow login logic using GitHub's device flow
// First, request a device code // First, request a device code
deviceCode, userCode, verificationURI, err := requestDeviceCode() deviceCode, userCode, verificationURI, err := requestDeviceCode()
@ -133,8 +151,13 @@ func performDeviceFlowLogin() error {
// requestDeviceCode initiates the device authorization flow // requestDeviceCode initiates the device authorization flow
func requestDeviceCode() (string, string, string, error) { 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{ payload := map[string]string{
"client_id": GithubClientID, "client_id": clientID,
"scope": "read:org read:user", "scope": "read:org read:user",
} }
@ -177,8 +200,13 @@ func requestDeviceCode() (string, string, string, error) {
// pollForToken polls for access token after user completes authorization // pollForToken polls for access token after user completes authorization
func pollForToken(deviceCode string) (string, error) { 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{ payload := map[string]string{
"client_id": GithubClientID, "client_id": clientID,
"device_code": deviceCode, "device_code": deviceCode,
"grant_type": "urn:ietf:params:oauth:grant-type:device_code", "grant_type": "urn:ietf:params:oauth:grant-type:device_code",
} }