Skip to content

feat(mcp-server): device flow client (scope: mcp-server)#204

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

feat(mcp-server): device flow client (scope: mcp-server)#204
liplus-lin-lay merged 1 commit into
mainfrom
198-oauth-device-flow

Conversation

@liplus-lin-lay
Copy link
Copy Markdown
Member

Closes #200

mcp-server/server/index.js の OAuth 実装を authorization_code + PKCE + localhost callback から Device Authorization Grant (RFC 8628) へ置き換え。Step 2 で刷新した Worker の /oauth/device_authorization + /oauth/token (grant_type=device_code) を利用し、ephemeral localhost port に依存しない認証経路に移行する。

stdio MCP は UI を持たないため user_code + verification_uri を stderr に出力。polling は server からの interval に従い、slow_down 受信時は interval を 5 秒増やす (RFC 8628 §3.5)。並行起動 (WebSocket boot と最初の tool call) は device flow lock で直列化。旧 oauth-tokens.json 検出時は一度だけ migration message を stderr に出してからファイル削除して device flow を開始する。

Part of #198

mcp-server/server/index.js の OAuth 実装を authorization_code + PKCE +
localhost callback から Device Authorization Grant (RFC 8628) へ置き換え。
Step 2 で刷新した Worker 側 endpoint (/oauth/device_authorization +
/oauth/token with grant_type=device_code) を利用し、ephemeral localhost
port に依存する chronic auth loop を構造的に排除する (#198 Step 3)。

主な変更:

- createServer / openBrowser / PKCE helper / OAuthPendingError を撤去。
  node:http と node:child_process への依存も削除。
- 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 に出力し、
  Claude Code のログに読める形で表示する。
- _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 を維持する。

受け入れ条件:
- process 再起動後、旧 tokens 持ち越しなしで device flow のみで認証完結。
- Claude Code ログに user_code + verification_uri が読める形で出る。
- 並行 Claude Code instance でも単一 device flow で tokens file を共有。

target files は #200 の scope どおり mcp-server/server/index.js 単独。
local-mcp/src/index.ts は Step 5 (#201) で別途対応するため触らない。

Closes #200
Part of #198

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@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 cc8bed5 Apr 20 2026, 05:59 AM

@liplus-lin-lay liplus-lin-lay merged commit 273d4d7 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:00
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(mcp-server): replace localhost callback with device flow client

1 participant