# MCP OAuth Proxy Evaluation

## Goal

Evaluate an opt-in proxy pattern for HTTP MCP servers when a tool only supports stdio transport or cannot inject OAuth tokens safely.

## Transport Options

| Option | Fit | Trade-off |
| --- | --- | --- |
| stdio proxy | Best compatibility for stdio-only clients. | Proxy owns token injection, refresh, logging controls, and revocation handling. |
| direct HTTP | Best when the tool supports HTTP MCP and auth natively. | Not portable to stdio-only tools. |
| tool-native OAuth | Preferred security ownership when available. | Behavior differs by IDE/CLI and may not support every MCP server. |

## Prototype Rules

- The proxy is disabled by default and must be explicitly enabled.
- Open Orchestra must not alter MCP config without user approval (`--enable --approve --approver <name>` in the evaluation command).
- HTTP MCP server URLs must use `https://`.
- Tokens can be stored only in OS secret storage (`keychain`, `libsecret`, `windows-credential`) or under approved local secure-file paths such as `~/.config/open-orchestra/secrets/`.
- Logs must never include access tokens, refresh tokens, auth codes, token endpoint responses, or bearer headers.
- Revocation is supported by deleting local token material and re-running authorization.

## Refresh Behavior

- Refresh is evaluated without real credentials by injecting a refresh function into `refreshMcpTokenIfNeeded`.
- Tokens refresh only inside the configured refresh window.
- The minimum refresh window is 30 seconds to avoid last-second token expiry during tool calls.
- HTTP MCP requests retry once after a `401` by refreshing the token and
  replaying the request with the new bearer token.

## Discovery And Registration

- OAuth metadata is discovered through RFC 8414 at
  `/.well-known/oauth-authorization-server`.
- Dynamic client registration follows RFC 7591 when `--dynamic-registration` is
  enabled and no `clientId` is configured.
- Registration stores only the returned client credentials in memory for the
  current start flow unless the caller persists config intentionally.
- Stdio proxy mode injects bearer tokens server-side; stdio clients never see
  token material.

## Security Review

- Token storage: use OS secret storage first; secure files only by explicit local path approval.
- Refresh: refresh before expiry and keep failures non-destructive so existing valid tokens are not overwritten by failed responses.
- Logs: redact token-shaped values and avoid logging raw provider responses.
- Revocation: document local token deletion and upstream OAuth app revocation.
- Configuration: keep MCP changes opt-in and reviewable; dry-run/evaluate before writing any config.

## CLI

```bash
orchestra mcp oauth-proxy evaluate --server-url https://mcp.example.com --enable --approve --approver <name> --json
orchestra mcp oauth-proxy start --server-url https://mcp.example.com --dynamic-registration --client-name "Open Orchestra" --enable --approve --approver <name>
```

The command returns risks and recommendations only; it does not write MCP configuration.
