Skip to main content
Glama
README.md
# Gosar MCP Server

An MCP server that lets Claude call the Gosar API on a user's behalf, authenticated
via Gosar's OAuth 2.0 + PKCE flow.

It acts as a bridge:

- To **Claude** (the MCP client), it behaves like a full OAuth authorization server —
  handling dynamic client registration and issuing its own short-lived tokens.
- To **Gosar**, it is the single, pre-registered OAuth client (public, PKCE-only) that
  performs the real Authorization Code + PKCE exchange described in Gosar's
  integration guide.

## Prerequisites

- Python 3.11+
- A Gosar OAuth client registered with the Gosar team (see "What we need from you" in
  the integration guide) — you need a `client_id` and an approved redirect URI.
- [ngrok](https://ngrok.com/) (or similar) if you want to test against the real Gosar
  API — Gosar's redirect URI must be HTTPS and match exactly, and Claude also needs an
  HTTPS URL to connect a remote MCP server to.

## 1. Install dependencies

```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```

## 2. Configure `.env`

Copy the values you have into `.env` at the project root:

```bash
# Real values from the Gosar team
GOSAR_API_BASE_URL=https://api.gosar.example
GOSAR_CLIENT_ID=your-registered-client-id
GOSAR_SCOPES=applications.read applications.write

# Your server's own public HTTPS URL (e.g. your ngrok URL). Gosar's registered
# redirect_uri must be exactly this + GOSAR_REDIRECT_PATH.
MCP_PUBLIC_BASE_URL=https://your-tunnel.ngrok-free.app
GOSAR_REDIRECT_PATH=/gosar/callback

MCP_HOST=0.0.0.0
MCP_PORT=8000

# Generate once and keep stable — see below
JWT_SIGNING_KEY=
```

Generate a signing key (Gosar is a public client with no secret, so this can't be
derived automatically — it's required):

```bash
python -c "import secrets; print(secrets.token_urlsafe(32))"
```

Paste the output into `JWT_SIGNING_KEY`. Keep it the same across restarts, or every
connected user gets logged out.

## 3. Expose your server over HTTPS (for real Gosar testing)

Claude and Gosar both require HTTPS. In a separate terminal:

```bash
ngrok http 8000
```

Copy the `https://...ngrok-free.app` URL into `MCP_PUBLIC_BASE_URL` in `.env`, and send
`{MCP_PUBLIC_BASE_URL}/gosar/callback` to the Gosar team as your registered redirect
URI.

## 4. Run the server

```bash
source .venv/bin/activate
python main.py
```

You should see:

```
Starting MCP server 'Gosar' with transport 'http' on http://0.0.0.0:8000/mcp
Uvicorn running on http://0.0.0.0:8000
```

### Auto-reload on code changes

`python main.py` does not reload — `mcp.run()` blocks and owns its own uvicorn
process, which can't be handed to a file-watching reloader. For development, run the
ASGI app in `gosar_mcp/asgi.py` under uvicorn directly instead:

```bash
uvicorn gosar_mcp.asgi:app --reload --reload-include ".env" --host 0.0.0.0 --port 8000
```

- `--reload` restarts the worker process whenever a `.py` file changes.
- `--reload-include ".env"` also restarts it when you edit `.env` (uvicorn only
  watches Python files by default, and env vars are only read once at process
  startup, so without this flag a `.env` edit needs a manual restart).
- Keep the port in sync with whatever your ngrok tunnel points at.

## 5. Sanity-check the OAuth wiring

With the server running, confirm discovery metadata is served:

```bash
curl -s http://127.0.0.1:8000/.well-known/oauth-authorization-server | python3 -m json.tool
```

You should see `applications.read`/`applications.write` in `scopes_supported` and
`S256` as the only PKCE method.

## 6. Connect it to Claude

In Claude's connector settings, add a remote MCP server pointing at:

```
https://your-tunnel.ngrok-free.app/mcp
```

Claude will register itself as an OAuth client against this server, redirect the user
through consent, then through Gosar's real Google sign-in + consent screen, and land
back here with an active connection. Ask Claude to call the `whoami` tool to confirm
it's authenticated as the expected Gosar account.

## Notes

- Token storage (client registrations + encrypted upstream Gosar tokens) defaults to
  an OS-appropriate encrypted file store on disk — no extra setup needed for local
  dev. See `gosar_mcp/auth.py` for where to point this at a different backend in
  production.
- `gosar_mcp/tools.py`'s `/applications` endpoint paths are placeholders — the
  integration guide only specifies the OAuth layer, not the Applications REST API
  shape. Confirm the real paths/payloads with the Gosar team and adjust there.