Metadata-Version: 2.4
Name: mcp-cloudrun-proxy
Version: 0.1.0
Summary: Cloud Run MCP transparent proxy (stdio <-> streamable HTTP)
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: google-auth>=2.0.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp<2,>=1.24.0
Requires-Dist: requests>=2.31.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"

# mcp-cloudrun-proxy

Transparent proxy for using an MCP server deployed on Cloud Run (Streamable HTTP)
as a local stdio MCP server.

Access to Cloud Run uses IAM Invoker + ID Token (Bearer), and the proxy
automatically refreshes expired tokens.

## What It Does

- Local side: acts as a stdio MCP server
- Remote side: connects to a Streamable HTTP MCP server
- Transparently relays JSON-RPC messages bidirectionally
- Adds `Authorization: Bearer <ID Token>` to all requests
- Refreshes tokens and retries/reconnects on `401`/`403`

## Prerequisites

- Python 3.10+
- A Cloud Run MCP endpoint (for example: `https://xxxx.run.app/mcp`)
- Valid ADC (Application Default Credentials) in the runtime environment
- Cloud Run Invoker role granted to the calling principal

## ADC Setup (Local Development)

If you use user credentials locally, you usually need to set up ADC first:

```bash
gcloud auth application-default login
```

Notes:

- `gcloud auth login` alone may not configure ADC (this tool uses ADC).
- If you use a service account, `GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json` also works.

## Usage

```bash
uvx mcp-cloudrun-proxy run \
  --url https://xxxx.run.app/mcp \
  --audience https://xxxx.run.app \
  --token-source google-auth \
  --log-level info \
  --refresh-margin 60
```

If you installed the command locally (for example with `pipx`, `uv tool`, or Nix),
replace `uvx mcp-cloudrun-proxy run` with `mcp-cloudrun-proxy run`.

Options:

- `--url` (required): Cloud Run MCP endpoint URL
- `--audience` (optional): ID token audience (inferred from `--url` if omitted)
- `--log-level`: `info` / `debug` / `warn`
- `--refresh-margin`: Seconds before expiry to refresh proactively (default: `60`)
- `--token-source` (required): `google-auth` / `gcloud`

Notes:

- If `--audience` is omitted, the proxy extracts `scheme://host[:port]` from `--url`.
- In many cases, the audience should be the Cloud Run service URL (without `/mcp`), but it must match your server-side expectations.
- In `--token-source gcloud` mode, the `audience` value is ignored because the gcloud user-credential path does not support audience-scoped ID tokens.
- Use `--token-source google-auth` for service account / metadata-based credentials.
- Use `--token-source gcloud` for local user ADC when you want token issuance via the `gcloud` CLI.

## Debug Command

Use the debug subcommand to test token issuance and Cloud Run access step by step.

```bash
uvx mcp-cloudrun-proxy debug \
  --url https://xxxx.run.app/mcp \
  --token-source gcloud
```

What it checks:

- ID token issuance (and prints which token source was used)
- Authenticated HTTP reachability to the Cloud Run endpoint

Tip:

- If local development changes are not reflected with `uvx`, try `uvx --refresh ...` or `uv cache clean`.

## Claude Desktop / Claude Code Configuration

Register this proxy as a stdio MCP server.
Client config schemas vary, so the examples below are generic patterns.

Recommended example using `uvx` (no local install):

```json
{
  "mcpServers": {
    "cloudrun-proxy": {
      "command": "uvx",
      "args": [
        "mcp-cloudrun-proxy",
        "run",
        "--url",
        "https://xxxx.run.app/mcp",
        "--audience",
        "https://xxxx.run.app",
        "--token-source",
        "gcloud"
      ]
    }
  }
}
```

## Nix

You can use this project via Nix without cloning the repository.

Run directly (no install):

```bash
nix run github:logicoffee/mcp-cloudrun-proxy -- \
  run \
  --url https://xxxx.run.app/mcp \
  --audience https://xxxx.run.app \
  --token-source google-auth
```

Install via Nix:

```bash
nix profile install github:logicoffee/mcp-cloudrun-proxy
```

After installation:

```bash
mcp-cloudrun-proxy run --url https://xxxx.run.app/mcp --audience https://xxxx.run.app --token-source google-auth
```

## Troubleshooting

- `401` / `403` keeps happening:
  - Check the `--audience` value first
  - If you are using user ADC, try `--token-source gcloud` and note that `audience` is ignored in gcloud mode
  - If Cloud Run requires an audience-scoped ID token, use a service account (`--token-source google-auth`)
  - Confirm the Cloud Run Invoker role is granted
  - Confirm ADC points to the expected account
- Connection closes immediately:
  - Confirm `--url` points to the MCP endpoint (`/mcp`)
  - Confirm Streamable HTTP transport is enabled on the Cloud Run side
- Logs are not visible:
  - Logs are written to stderr (stdout is reserved for the MCP protocol)

## Security Notes

- ID token contents are not logged
- Raw Authorization values are not logged or included in exception messages
- This proxy is intended as a secure relay that relies on Cloud Run IAM
