Skip to main content
Managing API keys, tokens, and other sensitive credentials securely is a critical aspect of building robust and safe applications. Universal MCP provides a flexible Store system to handle the storage and retrieval of these credentials.

The BaseStore Interface

All credential stores in Universal MCP inherit from the BaseStore abstract base class (defined in stores/store.py). This ensures a consistent API for interacting with different storage backends. The core methods are:
  • get(self, key: str) -> Any: Retrieve a value (credential) from the store by its key. Raises KeyNotFoundError if the key isn’t found.
  • set(self, key: str, value: str) -> None: Store a value under the given key.
  • delete(self, key: str) -> None: Delete a value from the store by its key. Raises KeyNotFoundError if the key isn’t found.

Available Store Implementations

Universal MCP comes with several built-in store implementations:
  1. MemoryStore:
    • Description: An in-memory dictionary. Credentials stored here persist only for the duration of the program’s execution.
    • Use Case: Excellent for testing, quick examples, or scenarios where persistent storage is not required or desired.
    • Configuration (type): "memory"
    from universal_mcp.stores import MemoryStore
    mem_store = MemoryStore()
    mem_store.set("MY_TEMP_KEY", "secret123")
    value = mem_store.get("MY_TEMP_KEY") # "secret123"
    
  2. EnvironmentStore:
    • Description: Uses operating system environment variables to store and retrieve credentials.
    • Use Case: Suitable for containerized environments (Docker, Kubernetes), CI/CD pipelines, or PaaS deployments where environment variables are the standard way to inject configuration and secrets.
    • Configuration (type): "environment"
    from universal_mcp.stores import EnvironmentStore
    env_store = EnvironmentStore()
    # Assuming an environment variable MY_API_KEY="env_secret" exists
    value = env_store.get("MY_API_KEY") # "env_secret"
    env_store.set("NEW_ENV_VAR", "new_value") # Sets os.environ["NEW_ENV_VAR"]
    
  3. KeyringStore:
    • Description: Leverages the system’s native secure credential storage facility (e.g., macOS Keychain, Windows Credential Manager, Linux Secret Service / KWallet). It uses the keyring Python library.
    • Use Case: The most secure option for storing sensitive data on a user’s machine or a server where system-level secure storage is available and appropriate. Ideal for desktop applications or long-running services.
    • Configuration (type): "keyring"
    • Requires: The keyring package (pip install keyring).
    from universal_mcp.stores import KeyringStore
    # 'app_name' is used as the service name in the system's keyring
    keyring_store = KeyringStore(app_name="MyUniversalMCPApp")
    keyring_store.set("MY_SECURE_API_KEY", "super_secret_from_keychain")
    value = keyring_store.get("MY_SECURE_API_KEY")
    
    The KeyringStore takes an app_name argument during initialization (defaults to “universal_mcp”), which corresponds to the “service name” used in the system’s keychain.

Configuring Stores

You can configure stores in two main places:
  1. Globally in ServerConfig: The store field in ServerConfig defines the default store for the server.
    // In local_config.json
    {
      "type": "local",
      "store": {
        "name": "my_default_mcp_store", // Used by KeyringStore as app_name
        "type": "keyring"
      },
      // ... other server settings
    }
    
    If an AppConfig doesn’t specify its own store, this default server store will be used for its Integration.
  2. Specifically in IntegrationConfig (within AppConfig): You can override the default server store or specify a store for a particular integration.
    // In local_config.json
    {
      // ...
      "apps": [
        {
          "name": "some-service",
          "integration": {
            "name": "SOME_SERVICE_KEY",
            "type": "api_key",
            "store": { // This integration will use an EnvironmentStore
              "type": "environment"
            }
          }
        },
        {
          "name": "another-service"
          // This app's integration will use the server's default store (if defined)
        }
      ]
    }
    
The store_from_config utility function is used internally to create the appropriate store instance based on the StoreConfig object.

Best Practices

  • Use KeyringStore for production or sensitive user-specific credentials on local machines.
  • Use EnvironmentStore for server-side deployments and CI/CD.
  • Use MemoryStore primarily for testing or transient data.
  • Always handle KeyNotFoundError and other StoreError exceptions when directly interacting with stores.
By choosing the right store, you can ensure your application’s credentials are managed appropriately for your security and operational needs.