Skip to content

feat(local-mcp): replace localhost callback with device flow client#205

Merged
liplus-lin-lay merged 1 commit into
mainfrom
198-oauth-device-flow
Apr 20, 2026
Merged

feat(local-mcp): replace localhost callback with device flow client#205
liplus-lin-lay merged 1 commit into
mainfrom
198-oauth-device-flow

Conversation

@liplus-lin-lay
Copy link
Copy Markdown
Member

Closes #201

local-mcp/src/index.ts を authorization_code + PKCE + localhost callback から
Device Authorization Grant (RFC 8628) へ置き換え。Step 3 (#204) の JS 実装を
TypeScript で忠実にポートし、_deviceFlowLock / checkLegacyTokensMigration /
RFC 8628 §3.5 polling error 処理を同等の挙動で実装した。
strict type check 用に @types/node + @types/ws を devDependencies に追加。

Part of #198

local-mcp/src/index.ts の OAuth 実装を authorization_code + PKCE +
localhost callback から Device Authorization Grant (RFC 8628) へ置き換え。
Step 2 (#203) で刷新した Worker 側 endpoint を利用し、ephemeral
localhost port 依存に起因する chronic auth loop を構造的に排除する。
Step 3 (#204) の mcp-server 版 JS 実装を TypeScript で忠実にポート
した Step 5 の実装 (#201)。

主な変更:

- node:http / node:crypto / node:child_process への依存と、createServer
  + PKCE helper + ブラウザ起動ロジックを削除。
- DeviceAuthorizationResponse / TokenPollingResponse を interface で型定義
  し、fetch レスポンスの as キャストで型を付与 (strict mode pass)。
- performOAuthFlow を device flow 版に再実装。
  requestDeviceAuthorization で user_code + verification_uri を取得し、
  pollForDeviceToken が interval 秒ごとに /oauth/token を叩く。
  authorization_pending は continue、slow_down は interval += 5s、
  access_denied / expired_token は throw (RFC 8628 §3.5 準拠)。
- stdio MCP は UI を持たないため、user_code / verification_uri /
  verification_uri_complete / expires_in を stderr に出力する。
- _deviceFlowLock で並行起動 (WebSocket boot と最初の tool call など)
  を直列化し、単一 device flow で両者が同じ tokens.json を共有できる。
- ensureClientRegistration は既存 client registration が device_code
  grant を含まない場合は再登録する (legacy PKCE 用 registration の
  自動マイグレーション)。redirect_uris は device flow で不要なので []。
- 旧 oauth-tokens.json 検出時は一度だけ stderr に移行メッセージを出し、
  ファイルを削除してから device flow を開始する
  (checkLegacyTokensMigration)。loadTokens も flow marker 不一致なら
  null を返すよう強化し、起動時に legacy tokens を掴まないようにした。
- 新規 tokens には flow: "device" marker を書き込み、refreshAccessToken
  による rotation 時にも marker を維持する。
- strict type check を通すため @types/node と @types/ws を
  devDependencies に追加。tsc --noEmit が green になる。

target files は #201 の scope どおり local-mcp/src/index.ts 単独。
mcp-server と worker は触らない (Step 3 / Step 2 で完了済)。

Closes #201
Part of #198
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
github-webhook-mcp 5df12b5 Apr 20 2026, 06:05 AM

@liplus-lin-lay liplus-lin-lay merged commit d39dfc7 into main Apr 20, 2026
3 checks passed
@liplus-lin-lay liplus-lin-lay deleted the 198-oauth-device-flow branch April 20, 2026 06:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(local-mcp): replace localhost callback with device flow client

1 participant