#!/usr/bin/env node
/**
* Strava OAuth Setup Script (Simplified)
*
* This script helps you obtain OAuth tokens for the Strava MCP server.
*/
const http = require('http');
const { parse } = require('url');
const readline = require('readline');
const PORT = 3000;
const REDIRECT_URI = `http://localhost:${PORT}/callback`;
console.log('\nπ΄ Strava MCP Server - OAuth Setup\n');
console.log('Prerequisites:');
console.log('1. Create a Strava API application at: https://www.strava.com/settings/api');
console.log('2. Set the Authorization Callback Domain to: localhost\n');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function question(query) {
return new Promise(resolve => rl.question(query, resolve));
}
async function main() {
const clientId = process.env.STRAVA_CLIENT_ID || await question('Enter your Strava Client ID: ');
const clientSecret = process.env.STRAVA_CLIENT_SECRET || await question('Enter your Strava Client Secret: ');
if (!clientId || !clientSecret) {
console.error('β Client ID and Client Secret are required');
process.exit(1);
}
console.log('\nπ Starting OAuth flow...');
// Create authorization URL
const authUrl = new URL('https://www.strava.com/oauth/authorize');
authUrl.searchParams.append('client_id', clientId);
authUrl.searchParams.append('redirect_uri', REDIRECT_URI);
authUrl.searchParams.append('response_type', 'code');
authUrl.searchParams.append('scope', 'read,activity:read_all,profile:read_all');
console.log('\nπ Please open this URL in your browser:\n');
console.log('β'.repeat(60));
console.log(authUrl.toString());
console.log('β'.repeat(60));
console.log('\nWaiting for authorization...\n');
// Create server to handle callback
const server = http.createServer(async (req, res) => {
const parsedUrl = parse(req.url, true);
if (parsedUrl.pathname === '/callback') {
const code = parsedUrl.query.code;
if (!code) {
res.writeHead(400, { 'Content-Type': 'text/html' });
res.end('<h1>Error: No authorization code received</h1>');
server.close();
rl.close();
process.exit(1);
}
try {
// Exchange code for tokens
const response = await fetch('https://www.strava.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: clientId,
client_secret: clientSecret,
code: code,
grant_type: 'authorization_code'
})
});
const tokens = await response.json();
if (!response.ok) {
throw new Error(tokens.message || 'Failed to get tokens');
}
// Display success and credentials
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(`
<html>
<head><title>Success!</title></head>
<body style="font-family: Arial; padding: 40px; text-align: center;">
<h1>β
Authorization Successful!</h1>
<p>You can close this window and return to the terminal.</p>
</body>
</html>
`);
console.log('\nβ
Authorization successful!\n');
console.log('Add these environment variables to your MCP settings:\n');
console.log('β'.repeat(60));
console.log(`STRAVA_ACCESS_TOKEN=${tokens.access_token}`);
console.log(`STRAVA_REFRESH_TOKEN=${tokens.refresh_token}`);
console.log(`STRAVA_CLIENT_ID=${clientId}`);
console.log(`STRAVA_CLIENT_SECRET=${clientSecret}`);
console.log('β'.repeat(60));
console.log('\nToken expires at:', new Date(tokens.expires_at * 1000).toLocaleString());
console.log('\nπ‘ Tip: Access tokens expire after 6 hours. Use the refresh token to get new ones.\n');
server.close();
rl.close();
} catch (error) {
console.error('\nβ Error getting tokens:', error.message);
res.writeHead(500, { 'Content-Type': 'text/html' });
res.end('<h1>Error getting tokens</h1><p>' + error.message + '</p>');
server.close();
rl.close();
process.exit(1);
}
}
});
server.listen(PORT, () => {
console.log(`β Local server started on port ${PORT}`);
});
}
main().catch(error => {
console.error('Error:', error);
rl.close();
process.exit(1);
});