> ## Documentation Index
> Fetch the complete documentation index at: https://onecli.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Credential Stubs for MCP Servers

> Create placeholder credential files so MCP servers can start without real secrets. The gateway fills in values at request time.

## When to use this

Use this guide when there is no provider-specific credential stubs page for your app. If a specific page exists (e.g. [Gmail](/guides/credential-stubs/gmail)), use that instead.

## How credential stubs work

Many MCP servers expect local credential files to exist before they'll start. When using the OneCLI gateway, real credentials are injected at request time, but the MCP server still needs structurally valid files to boot.

Stub files use the sentinel value `onecli-managed` wherever a real credential would go. When the MCP server makes an HTTP request using these stubs, the OneCLI gateway intercepts it and returns real credentials from your app connection.

## Common credential file locations

| MCP Server                            | Credential path                  |
| ------------------------------------- | -------------------------------- |
| `@gongrzhe/server-gmail-autoauth-mcp` | `~/.gmail-mcp/`                  |
| `@piotr-agier/google-drive-mcp`       | `~/.config/google-drive-mcp/`    |
| `@cocal/google-calendar-mcp`          | `~/.config/google-calendar-mcp/` |
| `@a-bonus/google-docs-mcp`            | `~/.config/google-docs-mcp/`     |
| `go.ngs.io/dropbox-mcp-server`        | `~/.dropbox-mcp-server/`         |
| `spotify-mcp-server`                  | `./spotify-config.json`          |
| `@aiondadotcom/mcp-salesforce`        | `~/.mcp-salesforce.json`         |
| `outlook-mcp`                         | `~/.outlook-mcp-tokens.json`     |

If the MCP server isn't listed, check its README or source for credential file paths (usually `~/.<app>-mcp/`, `~/.config/<app>/`, or a file in the project root).

## Stub patterns

MCP servers use one of three credential file patterns (A, B, and C). Some CLI tools instead read credentials from environment variables (Pattern D). Match the one your tool expects.

### Pattern A: Two files (Google OAuth)

Most Google MCP servers expect a **client key file** and a **token file**.

Client key file (e.g. `gcp-oauth.keys.json`, `credentials.json`, `client_secret.json`):

```json theme={null}
{
  "installed": {
    "client_id": "onecli-managed",
    "client_secret": "onecli-managed",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "redirect_uris": ["http://localhost:3000/oauth2callback"]
  }
}
```

Token file (e.g. `token.json`, `tokens.json`, `credentials.json`):

```json theme={null}
{
  "access_token": "onecli-managed",
  "refresh_token": "onecli-managed",
  "token_type": "Bearer",
  "expiry_date": 0
}
```

Some Google MCP servers use `expires_at` (ISO string) instead of `expiry_date` (unix ms). Check the server's source to match the field name.

### Pattern B: Single combined file (Dropbox, Spotify)

Some servers store client credentials and tokens in one file.

Dropbox style (`config.json`):

```json theme={null}
{
  "client_id": "onecli-managed",
  "client_secret": "onecli-managed",
  "access_token": "onecli-managed",
  "refresh_token": "onecli-managed",
  "expires_at": "1970-01-01T00:00:00Z"
}
```

Spotify style (`spotify-config.json`):

```json theme={null}
{
  "clientId": "onecli-managed",
  "clientSecret": "onecli-managed",
  "redirectUri": "http://127.0.0.1:8888/callback",
  "accessToken": "onecli-managed",
  "refreshToken": "onecli-managed",
  "expiresAt": 0
}
```

### Pattern C: Token-only file (Microsoft, Salesforce)

Some servers read client credentials from env vars and only store tokens on disk.

```json theme={null}
{
  "access_token": "onecli-managed",
  "refresh_token": "onecli-managed"
}
```

For these, the MCP server may also need env vars like `MS_CLIENT_ID` / `MS_CLIENT_SECRET`, which are handled separately by the OneCLI gateway's secret injection.

### Pattern D: CLI tools with environment variable auth

Some tools aren't MCP servers and never touch credential files. Instead, they accept a pre-obtained token through an environment variable and auto-load a `.env` file from the working directory at startup (for example, via the `dotenvy` crate). Use this pattern for those tools.

The `.env` file sets the token variable to `onecli-managed`. When the CLI makes an HTTPS request, it routes through `HTTPS_PROXY` and the gateway injects the real token at the network level, so the placeholder never needs to be a valid credential.

#### Example: `gws` (Google Workspace CLI)

<Steps>
  <Step title="Install gws">
    ```bash theme={null}
    npm install -g @googleworkspace/cli
    ```

    If your system's GLIBC is too old for the prebuilt binary, download the musl binary from the project's GitHub releases instead.
  </Step>

  <Step title="Create the .env stub">
    Create `/workspace/agent/.env`, the working directory `gws` runs from:

    ```bash theme={null}
    GOOGLE_WORKSPACE_CLI_TOKEN=onecli-managed
    ```
  </Step>

  <Step title="Run the command">
    ```bash theme={null}
    gws gmail +triage
    ```

    No env var prefix is needed. `gws` auto-loads `.env` from the working directory.
  </Step>
</Steps>

This works because `gws` uses the `dotenvy` crate to load `.env` from the working directory, and `GOOGLE_WORKSPACE_CLI_TOKEN` is the highest-priority auth method in `gws`.

<Tip>
  The `HTTPS_PROXY` environment variable is pre-set in all OneCLI agent containers. Any HTTP client that respects it (including Rust binaries like `gws`) routes through the gateway automatically, so real credentials are injected at the network level. You only set the placeholder locally.
</Tip>

## Forcing a token refresh

Set the expiry field to a past value so the MCP server immediately attempts a refresh via HTTP, which the gateway intercepts:

| Field name    | Expired value                   |
| ------------- | ------------------------------- |
| `expiry_date` | `0`                             |
| `expires_at`  | `"1970-01-01T00:00:00Z"`        |
| `expiresAt`   | `0`                             |
| `expiry`      | `"1970-01-01T00:00:00.000000Z"` |

## Rules

* **Never overwrite** existing files that don't contain `onecli-managed` values. The user may have real credentials.
* All sentinel values use the string `onecli-managed` so they're easy to detect programmatically.
* Create directories with `mkdir -p` if they don't exist.
* Set file permissions to `0600` when the MCP server expects it (most do).
