ワンクリックで
oauth-login
Complete OAuth login flow and store tokens for verification. Use when browser verification requires authenticated sessions.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Complete OAuth login flow and store tokens for verification. Use when browser verification requires authenticated sessions.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Generate EXECUTION_PLAN.md and scoped AGENTS.md files for a feature. Use after /feature-technical-spec to create the task breakdown.
Generate the greenfield execution plan plus root and scoped AGENTS.md files. Use after /technical-spec to create the phased task breakdown.
Guide discovery and discussion to determine how an AI coding agent can autonomously run and verify a specific user flow end to end. Use when the user asks what would be needed to test a flow, prove an app works, create an E2E/self-test harness, make agent verification repeatable, or evaluate whether an existing test setup lets the agent verify behavior. This skill is for shaping the verification approach before implementation: read the repo's product docs and existing verification contracts, identify the real user flow and channel under test, uncover missing controllable state or external dependencies, ask focused questions, and produce a concrete agent-runnable verification plan only after the flow is understood.
Exploratory conversation before /product-spec. Asks one question at a time, runs background research for open-source/off-the-shelf alternatives, and writes DISCOVERY_NOTES.md. Use when the user has an idea but hasn't scoped it yet.
Define feature requirements (problem, users, scope, acceptance criteria) through guided Q&A and write FEATURE_SPEC.md. Use when starting a new feature.
Define technical approach (architecture, integration points, data model) for a feature through guided Q&A and write FEATURE_TECHNICAL_SPEC.md. Use after /feature-spec.
SOC 職業分類に基づく
| name | oauth-login |
| description | Complete OAuth login flow and store tokens for verification. Use when browser verification requires authenticated sessions. |
| argument-hint | <provider> |
| allowed-tools | Bash, Read, Edit, Write, AskUserQuestion, WebFetch, mcp__playwright__* |
Complete an OAuth login flow for browser verification. Opens a browser to the OAuth
consent page, waits for callback, and stores tokens in the project's .env file.
| Provider | OAuth 2.0 Endpoint | Scopes |
|---|---|---|
| accounts.google.com | openid, email, profile | |
| github | github.com/login/oauth | read:user, user:email |
/oauth-login google
/oauth-login github
OAuth App Credentials Required
Before running this command, the user must have created an OAuth application with the provider and have the client ID and secret ready.
Google:
http://localhost:3847/oauth/callbackGitHub:
http://localhost:3847/oauth/callbackBrowser MCP Available
Playwright MCP or similar browser tool must be available for automated flow.
Copy this checklist and track progress:
OAuth Login Progress:
- [ ] Step 1: Check provider argument
- [ ] Step 2: Check for existing credentials
- [ ] Step 3: Collect OAuth app credentials
- [ ] Step 4: Generate state parameter
- [ ] Step 5: Build authorization URL
- [ ] Step 6: Start callback server
- [ ] Step 7: Open browser to auth URL
- [ ] Step 8: Wait for callback
- [ ] Step 9: Exchange code for tokens
- [ ] Step 10: Store tokens in .env
- [ ] Step 11: Verify token validity
- [ ] Step 12: Report success
If $1 is not provided or not recognized:
OAUTH LOGIN
===========
Usage: /oauth-login <provider>
Supported providers:
google - Google OAuth 2.0
github - GitHub OAuth
Example: /oauth-login google
Read .env file and check for existing OAuth tokens:
grep -E "^OAUTH_(GOOGLE|GITHUB)_" .env 2>/dev/null || true
If tokens exist for this provider, ask:
Question: "OAuth tokens for {provider} already exist. What would you like to do?"
Header: "Existing tokens"
Options:
- Label: "Refresh tokens"
Description: "Re-authenticate and get new tokens"
- Label: "Keep existing"
Description: "Exit without changes"
Use AskUserQuestion to collect OAuth app credentials:
Question: "Enter your {Provider} OAuth Client ID:"
Header: "Client ID"
Then:
Question: "Enter your {Provider} OAuth Client Secret:"
Header: "Client Secret"
Add to .env:
OAUTH_{PROVIDER}_CLIENT_ID=<client_id>
OAUTH_{PROVIDER}_CLIENT_SECRET=<client_secret>
After writing to .env, read back the file to confirm the credentials were stored correctly. If the .env file does not exist yet, create it first.
Create a temporary callback server to receive the OAuth code.
Write the contents of callback-server.js to a temp file, then execute it:
# Copy callback server script to temp location
cp "$(dirname "$0")/callback-server.js" /tmp/oauth-callback-server.js 2>/dev/null || \
cp .claude/skills/oauth-login/callback-server.js /tmp/oauth-callback-server.js
# Start callback server as BACKGROUND PROCESS
node /tmp/oauth-callback-server.js &
CALLBACK_PID=$!
echo "Callback server started (PID: $CALLBACK_PID, background process)"
# Verify the server started successfully
sleep 1
curl -sf http://localhost:3847/ -o /dev/null 2>&1 || echo "WARNING: Callback server may not have started"
Verify server is listening before proceeding by running curl -sf http://localhost:3847/ -o /dev/null and checking the exit code. If the server failed to start (port in use, Node.js error), check the error output and try an alternate port (3848, 3849) before continuing.
Google:
https://accounts.google.com/o/oauth2/v2/auth?
client_id={CLIENT_ID}&
redirect_uri=http://localhost:3847/oauth/callback&
response_type=code&
scope=openid%20email%20profile&
access_type=offline&
prompt=consent
GitHub:
https://github.com/login/oauth/authorize?
client_id={CLIENT_ID}&
redirect_uri=http://localhost:3847/oauth/callback&
scope=read:user%20user:email
Use Playwright MCP to open the authorization URL:
mcp__playwright__browser_navigate with url={auth_url}
Display to user:
OAUTH AUTHORIZATION
===================
Opening browser for {Provider} authorization...
Please complete the login in the browser window.
This command will wait for you to complete authorization.
If the browser doesn't open, visit this URL:
{auth_url}
Poll for the callback result:
# Wait up to 120 seconds for callback
for i in $(seq 1 120); do
if [ -f /tmp/oauth-code.txt ]; then
CODE=$(cat /tmp/oauth-code.txt)
rm /tmp/oauth-code.txt
break
fi
if [ -f /tmp/oauth-error.txt ]; then
ERROR=$(cat /tmp/oauth-error.txt)
rm /tmp/oauth-error.txt
echo "OAuth error: $ERROR"
exit 1
fi
sleep 1
done
Google token exchange:
curl -s -X POST https://oauth2.googleapis.com/token \
-d "code=$CODE" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "redirect_uri=http://localhost:3847/oauth/callback" \
-d "grant_type=authorization_code"
GitHub token exchange:
curl -s -X POST https://github.com/login/oauth/access_token \
-H "Accept: application/json" \
-d "code=$CODE" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET"
Check the HTTP response status code from the token exchange before parsing. If the response contains an error field or is not valid JSON, report the error and do not proceed to token storage.
Parse response for:
access_tokenrefresh_token (Google only)expires_inAfter obtaining the token, verify it is valid by making a lightweight test API call (e.g., fetch the user profile endpoint). If the test call fails, report the token as invalid and retry the OAuth flow.
Google verification:
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" https://www.googleapis.com/oauth2/v2/userinfo
GitHub verification:
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" https://api.github.com/user
If the response indicates an error (HTTP 401 or invalid token), report: "Token verification failed — token appears invalid" and restart the OAuth flow from Step 5.
Calculate expiry timestamp and store in .env:
EXPIRY=$(date -v+${EXPIRES_IN}S +%s 2>/dev/null || date -d "+${EXPIRES_IN} seconds" +%s)
Add/update in .env:
OAUTH_{PROVIDER}_ACCESS_TOKEN={access_token}
OAUTH_{PROVIDER}_REFRESH_TOKEN={refresh_token}
OAUTH_{PROVIDER}_TOKEN_EXPIRY={expiry_timestamp}
After writing tokens to .env, read back the file to verify the token variables are present and non-empty. Do not proceed to the next step if tokens are missing.
Update .claude/verification-config.json to use OAuth:
{
"auth": {
"strategy": "oauth",
"provider": "{provider}",
"tokenVar": "OAUTH_{PROVIDER}_ACCESS_TOKEN",
"refreshTokenVar": "OAUTH_{PROVIDER}_REFRESH_TOKEN",
"expiryVar": "OAUTH_{PROVIDER}_TOKEN_EXPIRY"
}
}
After updating verification-config.json, read the file back to confirm the auth section was written correctly and the JSON is valid.
# Kill callback server if still running
kill $CALLBACK_PID 2>/dev/null || true
rm -f /tmp/oauth-callback-server.js /tmp/oauth-code.txt /tmp/oauth-error.txt
OAUTH LOGIN COMPLETE
====================
Provider: {Provider}
Access Token: Stored in .env as OAUTH_{PROVIDER}_ACCESS_TOKEN
Refresh Token: {Stored | Not provided (GitHub)}
Token Expiry: {date/time}
verification-config.json updated with OAuth settings.
The access token will be automatically refreshed before verification runs
if it's within 5 minutes of expiry.
This command also handles token refresh when called with --refresh:
/oauth-login google --refresh
Refresh flow:
OAUTH_{PROVIDER}_REFRESH_TOKEN from .envGoogle refresh:
curl -s -X POST https://oauth2.googleapis.com/token \
-d "refresh_token=$REFRESH_TOKEN" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "grant_type=refresh_token"
OAUTH_{PROVIDER}_ACCESS_TOKEN and OAUTH_{PROVIDER}_TOKEN_EXPIRY in .envNote: GitHub tokens don't expire unless revoked, so no refresh needed.
| Error | Action |
|---|---|
| Callback server port in use | Try port 3848, 3849, etc. |
| User cancels consent | Show error, suggest retry |
| Token exchange fails | Show API error, suggest checking credentials |
| Browser MCP unavailable | Provide manual URL, ask user to paste code |
If user is still in browser after 120s timeout:
If browser MCP is completely unavailable:
If OAuth app credentials are invalid:
If callback server cannot start on any port:
.env which should be in .gitignore