Skip to main content
Glama
decode-oauth-token.cjs7.33 kB
#!/usr/bin/env node const axios = require('axios'); const https = require('https'); const crypto = require('crypto'); const axiosInstance = axios.create({ httpsAgent: new https.Agent({ rejectUnauthorized: false }), timeout: 30000 }); const MCP_BASE = 'https://portland-writes-pale-colours.trycloudflare.com'; async function decodeOAuthToken() { console.log('\n════════════════════════════════════════════════════════════'); console.log(' 🔍 DECODING OAUTH TOKEN STRUCTURE'); console.log('════════════════════════════════════════════════════════════\n'); try { // OAuth Authentication console.log('1️⃣ Getting OAuth token...'); const metadataResponse = await axiosInstance.get(`${MCP_BASE}/.well-known/oauth-authorization-server`); const registerResponse = await axiosInstance.post(`${MCP_BASE}/register`, { client_name: "Claude Desktop", grant_types: ["authorization_code", "refresh_token"], response_types: ["code"], token_endpoint_auth_method: "client_secret_post", scope: "claudeai", redirect_uris: ["https://claude.ai/api/mcp/auth_callback"] }); const clientId = registerResponse.data.client_id; const loginResponse = await axiosInstance.post(`${MCP_BASE}/login`, 'username=david%2Ballcloud%40umbrellacost.com&password=Dsamsung1%21123&state=test&client_id=' + clientId, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, maxRedirects: 0, validateStatus: (status) => status === 302 } ); const cookies = loginResponse.headers['set-cookie']; const sidCookie = cookies?.find(c => c.startsWith('sid=')); const sid = sidCookie?.split(';')[0].split('=')[1]; const codeVerifier = crypto.randomBytes(32).toString('base64url'); const codeChallenge = crypto.createHash('sha256').update(codeVerifier).digest('base64url'); const authResponse = await axiosInstance.get(`${MCP_BASE}/authorize`, { params: { response_type: 'code', client_id: clientId, redirect_uri: 'https://claude.ai/api/mcp/auth_callback', state: 'test-state', code_challenge: codeChallenge, code_challenge_method: 'S256' }, headers: { 'Cookie': `sid=${sid}` } }); const codeMatch = authResponse.data.match(/code=([^&\"]+)/); const authCode = codeMatch ? codeMatch[1] : null; const tokenResponse = await axiosInstance.post(`${MCP_BASE}/oauth/token`, new URLSearchParams({ grant_type: 'authorization_code', code: authCode, redirect_uri: 'https://claude.ai/api/mcp/auth_callback', client_id: clientId, code_verifier: codeVerifier }).toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ); console.log('✅ Got OAuth token response\n'); console.log('2️⃣ Token Response Structure:'); console.log('─────────────────────────────────────────────────────'); // Show all fields in the token response Object.keys(tokenResponse.data).forEach(key => { const value = tokenResponse.data[key]; if (typeof value === 'string' && value.length > 100) { console.log(` ${key}: [${value.substring(0, 50)}...]`); } else { console.log(` ${key}: ${value}`); } }); console.log('\n3️⃣ API Key Analysis:'); console.log('─────────────────────────────────────────────────────'); const apikey = tokenResponse.data.apikey; if (apikey) { console.log(` Full apikey: ${apikey}`); // Parse the apikey structure const parts = apikey.split(':'); console.log(`\n Parsed components (${parts.length} parts):`); parts.forEach((part, index) => { console.log(` Part ${index + 1}: ${part}`); }); // Check against expected format console.log('\n Expected format: userKey:accountKey:divisionId'); if (parts.length >= 3) { console.log(` userKey: ${parts[0]}`); console.log(` accountKey: ${parts[1]}`); console.log(` divisionId: ${parts[2]}`); } // Compare with MANUAL_ANSWERS.txt expected value const expectedApiKey = '57ade50e-c9a8-49f3-8ce7-28d44536a669:22676:139'; console.log(`\n Expected from MANUAL_ANSWERS.txt: ${expectedApiKey}`); console.log(` Match: ${apikey === expectedApiKey ? '✅ YES' : '❌ NO'}`); if (apikey !== expectedApiKey) { console.log('\n ⚠️ API key does not match expected format!'); console.log(' This could be why division 139 is not being applied.'); } } else { console.log(' ❌ No apikey field found in token response'); } console.log('\n4️⃣ Accounts Data in Token Response:'); console.log('─────────────────────────────────────────────────────'); if (tokenResponse.data.accounts) { console.log(' ✅ Found accounts data in token response'); const accounts = JSON.parse(tokenResponse.data.accounts); console.log(` Number of accounts: ${accounts.length}`); // Look for Bank Leumi const bankLeumi = accounts.find(acc => { const accountKey = acc.accountKey || acc.account_key || acc.accountId || acc.account_id; return String(accountKey) === '22676'; }); if (bankLeumi) { console.log('\n Bank Leumi account found:'); console.log(JSON.stringify(bankLeumi, null, 2).split('\n').map(line => ' ' + line).join('\n')); } } else { console.log(' ❌ No accounts field in token response'); } } catch (error) { console.error('\n❌ Error:', error.message); if (error.response) { console.error('Status:', error.response.status); console.error('Response:', JSON.stringify(error.response.data, null, 2)); } } } decodeOAuthToken().catch(console.error);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/daviddraiumbrella/invoice-monitoring'

If you have feedback or need assistance with the MCP directory API, please join our Discord server