Skip to main content
Glama

New Relic MCP Server

by piekstra
credentials.py7.06 kB
#!/usr/bin/env python3 """ Secure credential management for New Relic MCP Server using macOS Keychain """ import logging import os from typing import Optional import keyring logger = logging.getLogger(__name__) SERVICE_NAME = "newrelic-mcp-server" class SecureCredentials: """Secure credential storage using macOS Keychain""" @staticmethod def store_api_key(api_key: str) -> None: """Store New Relic API key securely in keychain""" try: keyring.set_password(SERVICE_NAME, "api_key", api_key) logger.info("API key stored securely in keychain") except Exception as e: logger.error(f"Failed to store API key in keychain: {e}") raise @staticmethod def get_api_key() -> Optional[str]: """Retrieve New Relic API key from keychain or environment""" # First try keychain try: api_key = keyring.get_password(SERVICE_NAME, "api_key") if api_key: logger.info("Retrieved API key from keychain") return api_key except Exception as e: logger.warning(f"Failed to retrieve API key from keychain: {e}") # Fallback to environment variables for backwards compatibility api_key = os.getenv("NEWRELIC_API_KEY") or os.getenv("NEW_RELIC_API_KEY") if api_key: logger.warning( "Using API key from environment variable " "(consider migrating to keychain)" ) return api_key @staticmethod def store_account_id(account_id: str) -> None: """Store New Relic account ID securely in keychain""" try: keyring.set_password(SERVICE_NAME, "account_id", account_id) logger.info("Account ID stored securely in keychain") except Exception as e: logger.error(f"Failed to store account ID in keychain: {e}") raise @staticmethod def get_account_id() -> Optional[str]: """Retrieve New Relic account ID from keychain or environment""" # First try keychain try: account_id = keyring.get_password(SERVICE_NAME, "account_id") if account_id: logger.info("Retrieved account ID from keychain") return account_id except Exception as e: logger.warning(f"Failed to retrieve account ID from keychain: {e}") # Fallback to environment variable for backwards compatibility account_id = os.getenv("NEWRELIC_ACCOUNT_ID") if account_id: logger.warning( "Using account ID from environment variable " "(consider migrating to keychain)" ) return account_id @staticmethod def get_region() -> str: """Get New Relic region (stored as env var as it's not sensitive)""" return os.getenv("NEWRELIC_REGION", "US") @staticmethod def delete_credentials() -> None: """Remove all stored credentials from keychain""" try: keyring.delete_password(SERVICE_NAME, "api_key") logger.info("API key removed from keychain") except keyring.errors.PasswordDeleteError: logger.info("No API key found in keychain to delete") except Exception as e: logger.error(f"Failed to delete API key from keychain: {e}") try: keyring.delete_password(SERVICE_NAME, "account_id") logger.info("Account ID removed from keychain") except keyring.errors.PasswordDeleteError: logger.info("No account ID found in keychain to delete") except Exception as e: logger.error(f"Failed to delete account ID from keychain: {e}") @staticmethod def list_stored_credentials() -> dict: """List what credentials are stored (True/False, not actual values)""" credentials = {} try: api_key = keyring.get_password(SERVICE_NAME, "api_key") credentials["api_key_in_keychain"] = api_key is not None except Exception: credentials["api_key_in_keychain"] = False try: account_id = keyring.get_password(SERVICE_NAME, "account_id") credentials["account_id_in_keychain"] = account_id is not None except Exception: credentials["account_id_in_keychain"] = False credentials["api_key_in_env"] = bool( os.getenv("NEWRELIC_API_KEY") or os.getenv("NEW_RELIC_API_KEY") ) credentials["account_id_in_env"] = bool(os.getenv("NEWRELIC_ACCOUNT_ID")) credentials["region"] = os.getenv("NEWRELIC_REGION", "US") return credentials def setup_credentials_cli(): """Interactive CLI for setting up secure credentials""" import getpass print("=== New Relic MCP Server - Secure Credential Setup ===\n") # Show current status status = SecureCredentials.list_stored_credentials() print("Current credential status:") print(f" API Key in keychain: {'✓' if status['api_key_in_keychain'] else '✗'}") print(f" API Key in environment: {'✓' if status['api_key_in_env'] else '✗'}") print( f" Account ID in keychain: " f"{'✓' if status['account_id_in_keychain'] else '✗'}" ) print(f" Account ID in environment: {'✓' if status['account_id_in_env'] else '✗'}") print(f" Region: {status['region']}\n") # API Key setup if not status["api_key_in_keychain"]: while True: api_key = getpass.getpass( "Enter your New Relic API Key (starts with NRAK-): " ).strip() if api_key.startswith("NRAK-"): try: SecureCredentials.store_api_key(api_key) print("✓ API key stored securely in keychain\n") break except Exception as e: print(f"✗ Failed to store API key: {e}") break else: print( "✗ Invalid API key format. " "New Relic API keys start with 'NRAK-'" ) else: print("✓ API key already stored in keychain\n") # Account ID setup if not status["account_id_in_keychain"]: account_id = input( "Enter your New Relic Account ID " "(optional, press Enter to skip): " ).strip() if account_id: try: SecureCredentials.store_account_id(account_id) print("✓ Account ID stored securely in keychain\n") except Exception as e: print(f"✗ Failed to store account ID: {e}") else: print("✓ Account ID already stored in keychain\n") print( "Setup complete! You can now remove the API key from your " "environment variables and Claude Desktop config." ) print("The server will automatically use the secure keychain storage.") if __name__ == "__main__": setup_credentials_cli()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/piekstra/newrelic-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server