A sandbox that cannot open a browser can still use the same GitHub allowlist. First enable MCP, then use this flow with a client that implements the Machine Memory protocol; ordinary MCP clients do not automatically use it.
- Register a public client (
token_endpoint_auth_method=none) at/registerwith aredirect_uri, such ashttp://127.0.0.1/callback. No listener, inbound connection, or tunnel is needed. Retain a random PKCEcode_verifieron the headless machine. - Send an
application/x-www-form-urlencodedPOST /device/startwithclient_id,redirect_uri,code_challenge_method=S256, and the base64url-encoded SHA-256code_challenge. Includeresource=https://<router-url>/mcp. The response hasuser_code,device_code,verification_uri,expires_in, andinterval. - Open
verification_uri(https://<router-url>/activate), enteruser_code, and finish the GitHub login. The page says approved. It does not show a token. - Poll
POST /device/pollwith form-encodeddevice_codeandclient_id, waiting at leastintervalseconds between requests. HTTP 400authorization_pendingmeans keep waiting;slow_downmeans wait at least another interval. HTTP 200 returns{ "code": "..." }exactly once.access_denied,expired_token, or HTTP 500server_errorends the attempt. - Exchange that code at
POST /tokenwithgrant_type=authorization_code,code,client_id, the sameredirect_uri,resource, and the retainedcode_verifier. The standard OAuth provider issues the access and refresh tokens.
The session expires 10 minutes after it starts. Approval and code retrieval are single-use; if the successful poll response is lost, start a new login. Keep device_code and code_verifier private; only user_code belongs in the browser. Do not send MACHINE_MEMORY_DB_TOKEN to an MCP client. This replaces the old custom device grant at /token; it is not RFC 8628, and mcp-remote --device-code does not apply.
Deployment creates a dedicated ${oauthKvName}-devices D1 database and applies iac/oauth-migrations for atomic device approvals. It does not use the project-memory database. OAuth clients and tokens remain in the provider’s KV namespace. Expired device rows are removed when a new login starts, and expiry is enforced on every read and transition.
Next: Init for agent instructions, then Tools.
If something fails
See Troubleshooting → MCP for OAuth and sandbox credential issues.