# @sectigo/mcp-proxy

A lightweight stdio-to-HTTP proxy for the SCM MCP server. Handles OAuth token
acquisition and refresh automatically so you never need to manually run
`scm-mcp-login.sh` again.

## How It Works

```
Copilot CLI ──stdio──▶ mcp-proxy ──HTTP + Bearer──▶ MCP Server
                          │
                          └── Keycloak (client_credentials)
```

1. **Discovery** — fetches `.well-known/oauth-protected-resource` from the MCP server to find the Keycloak token endpoint
2. **Token fetch** — uses `client_credentials` grant to get an access token
3. **Auto-refresh** — refreshes the token before it expires (configurable buffer)
4. **Proxy** — reads JSON-RPC from stdin, POSTs to the MCP server with the Bearer token, writes the response to stdout

## Installation

### 1. Configure npm for the GitHub Packages registry

Add the following to your `~/.npmrc`:

```ini
@sectigo:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_PAT
```

Replace `YOUR_GITHUB_PAT` with a **classic** Personal Access Token that has the
`read:packages` scope. (Fine-grained tokens do not support GitHub Packages yet.)

To create a PAT: [GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)](https://github.com/settings/tokens/new) — select only the `read:packages` scope.

### 2. Install globally

```bash
npm install -g @sectigo/mcp-proxy
```

This makes the `mcp-proxy` command available in your PATH.

## Prerequisites

- Node.js 20+ (uses built-in `fetch`)
- OAuth client credentials for the target MCP server (request from your SCM administrator)

## Configuration

Add to your MCP client config (e.g. `~/.copilot/mcp-config.json` for GitHub Copilot CLI):

```json
{
  "mcpServers": {
    "scm-mcp": {
      "command": "mcp-proxy",
      "args": [],
      "env": {
        "MCP_URL": "https://your-scm-instance.example.com/mcp",
        "MCP_CLIENT_ID": "your-client-id",
        "MCP_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}
```

Restart your MCP client — the proxy starts automatically when the client needs it.

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `MCP_URL` | Yes | MCP server endpoint (e.g. `https://mcp.ccmqa.com/mcp`) |
| `MCP_CLIENT_ID` | Yes | OAuth client ID |
| `MCP_CLIENT_SECRET` | Yes | OAuth client secret |
| `MCP_REFRESH_BUFFER` | No | Seconds before expiry to refresh (default: `60`) |

## Manual Testing

```bash
export MCP_URL="https://mcp.ccmqa.com/mcp"
export MCP_CLIENT_ID="your-client-id"
export MCP_CLIENT_SECRET="your-secret"

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | mcp-proxy
```

Diagnostic messages appear on stderr. MCP protocol messages appear on stdout.

## Updating

```bash
npm update -g @sectigo/mcp-proxy
```

## Troubleshooting

| Symptom | Fix |
|---------|-----|
| `E404 Not Found` on npmjs.org | Add `@sectigo:registry=https://npm.pkg.github.com` to `~/.npmrc` |
| `E401 Unauthorized` | Add `//npm.pkg.github.com/:_authToken=<PAT>` to `~/.npmrc` |
| `E403 Forbidden` | Ensure your PAT has `read:packages` scope and is not expired |
| Token fetch timeout | Check `MCP_URL` is reachable and `.well-known/oauth-protected-resource` responds |
