Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/0-requirements.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,21 @@ Requirements:
OAuth flow で要求する localhost callback URI を全て含む場合だけ再利用し、
含まない場合は authorization 前に client registration を置き換える

### Bridge OAuth recovery(issue #250)

ローカル bridge は credential を取得するたびに共有 token ファイルを読み、別の
bridge process が保存した更新も取り込む。401 または refresh 失敗で無効と判明した
token を、その process がメモリや disk からそのまま再採用してはならない。
有効な既存 credential は引き続き利用する。同時呼び出しは一つの authorization
attempt を共有し、pending の呼び出しは速やかに戻る。後続の呼び出しは完了・失敗・
5 分の timeout を観測でき、未処理 Promise rejection を発生させない。
callback page の成功表示は token 交換と保存の成功後に出す。error と log は
token・code・state・verifier・authorization URL を含めない。
MCP protocol と検索の意味は変更しない。
新しい token record は発行時の client ID を保持し、別 process が共有 client
registration を置き換えてもその ID で refresh する。旧 record は共有 registration
を fallback として使う。token と registration は完成したファイルを atomic に置換する。

## Storage Rules

### Canonical memory surfaces
Expand Down
15 changes: 15 additions & 0 deletions docs/0-requirements.md
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,21 @@ Requirements:
URI set covers every localhost callback URI requested for the current OAuth
flow; otherwise register a replacement client before authorization

### Bridge OAuth recovery (issue #250)

The local bridge reads shared token storage on each credential request, including
updates made by another bridge process. A token rejected with 401 or a failed
refresh must not be reused unchanged from memory or disk in that process. Valid
existing credentials remain usable. Concurrent calls share one authorization
attempt; a pending call returns promptly and a later call observes completion,
failure, or the five-minute timeout without an unhandled promise rejection.
The callback page reports success only after token exchange and storage succeed.
Errors and logs must not expose tokens, codes, state, verifiers, or authorization
URLs. This changes neither MCP protocols nor search semantics.
New token records retain their issuing client ID for refresh even when another
process replaces shared client registration; legacy records use that registration
as a fallback. Token and registration writes replace complete files atomically.

## Storage Rules

### Canonical memory surfaces
Expand Down
25 changes: 20 additions & 5 deletions mcp-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,21 +120,36 @@ The `type` filter accepts: `issue`, `pull_request`, `release`, `doc`, `wiki_doc`
is cached for the current localhost callback URIs.
3. It starts a one-shot localhost HTTP listener on a random port and opens the browser to the Worker's authorization endpoint.
4. After you approve, the Worker redirects to `http://127.0.0.1:<port>/callback` with an authorization code.
5. The proxy exchanges the code for tokens (PKCE S256) and saves them.
6. Subsequent calls reuse the access token and silently refresh when it nears expiry. On `401` from the Worker, the proxy invalidates its cached tokens and re-authenticates.
5. The proxy exchanges the code for tokens (PKCE S256) and saves them before the
browser shows success. Exchange or storage failures show an authorization failure.
6. Subsequent calls read shared token storage, including another process's updates,
and silently refresh when the token nears expiry. A `401` rejects the bearer
actually sent, including the transport's final retry. Rejected access tokens and
failed refresh credentials are excluded in that process; a fresh token from disk
can still be used. New records retain the issuing client ID for refresh; older
records use the shared client registration as a fallback.

While authorization is pending, tool calls return an authentication requirement
after a short wait. Retry after completing the browser flow: the running proxy
uses the saved tokens. A failed flow or five-minute timeout is reported on a later
call; retry again to start a new flow. Concurrent calls share one browser attempt.

The browser callback never leaves your machine; the authorization code is delivered directly to the local listener.

## Troubleshooting

- **Browser does not open.** The proxy logs the authorization URL to stderr; copy it into a browser manually.
- **Browser does not open.** Check that your system has a working default browser.
The proxy does not log authorization URLs or credentials.
- **`redirect_uri is not associated with this application`.** Upgrade the
proxy. Current versions replace cached client registrations whose redirect
URI set does not cover the callback port selected for this authorization.
- **`OAuth callback timed out after 5 minutes`.** Re-invoke any tool to restart the flow.
- **`OAuth callback timed out after 5 minutes`.** Retry the tool to start a new flow.
- **`Failed to reach worker`.** Check that `RAG_WORKER_URL` is correct and reachable from your machine.
- **`Unsupported protocol version`, or a tool that answers with a protocol error instead of results.** The proxy predates the 2026-07-28 flip. Quit Claude Desktop fully and reopen so `npx` fetches the current version; if your config pins a version, move the pin forward first.
- **Stale credentials.** Remove `~/.github-rag-mcp/oauth-tokens.json` (and optionally `oauth-client.json`) and retry.
- **Authentication required after authorizing.** Retry the tool after the browser
confirms success. The running proxy reads the newly saved token; restarting or
deleting credentials is not required for this recovery. A browser failure page
means exchange or storage did not complete successfully.

## Links

Expand Down
2 changes: 1 addition & 1 deletion mcp-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
],
"scripts": {
"start": "node server/index.js",
"test": "node --check server/index.js && node --check server/tools.js && node --test test/oauth-client-registration.test.js test/search-tool-schema.test.js",
"test": "node --check server/index.js && node --check server/oauth.js && node --check server/tools.js && node --test test/*.test.js",
"pack:mcpb": "mcpb pack"
},
"dependencies": {
Expand Down
Loading
Loading