Obtenir l'URL d'autorisation Strava
strava_get_auth_urlGenerate the Strava OAuth2 authorization URL to obtain a temporary code. Open the URL in a browser, authorize the app, then copy the 'code' parameter from the redirect URL for token exchange.
Instructions
Génère l'URL OAuth2 Strava. Ouvrir cette URL dans un navigateur, autoriser l'application, puis copier le paramètre 'code' depuis l'URL de redirection et le passer à strava_exchange_token.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/auth/authTools.ts:19-43 (handler)The async handler function for the 'strava_get_auth_url' tool. It checks clientId config, starts the OAuth callback server, builds the authorization URL via buildAuthorizationUrl(), and returns the URL to the user.
async () => { if (!config.clientId) { return { content: [ { type: "text", text: "Erreur : STRAVA_CLIENT_ID non configuré. Copie .env.example en .env et renseigne tes credentials.", }, ], }; } const redirectUri = config.redirectUri; const portMatch = redirectUri.match(/:(\d+)\//); const port = portMatch ? parseInt(portMatch[1], 10) : 8080; startOAuthCallbackServer(port); const url = buildAuthorizationUrl(); return { content: [ { type: "text", text: `Ouvre cette URL dans ton navigateur :\n\n${url}\n\nUne fois que tu as autorisé l'application sur Strava, la page affichera "✓ Authentification réussie !" et les tokens seront sauvegardés automatiquement. Tu n'as rien d'autre à faire.`, }, ], }; } - src/auth/authTools.ts:8-44 (registration)The 'strava_get_auth_url' tool is registered inside registerAuthTools() function on line 9 via server.registerTool('strava_get_auth_url', ...). The registration includes the title, description, empty inputSchema, and the handler.
export function registerAuthTools(server: McpServer): void { server.registerTool( "strava_get_auth_url", { title: "Obtenir l'URL d'autorisation Strava", description: "Génère l'URL OAuth2 Strava. Ouvrir cette URL dans un navigateur, " + "autoriser l'application, puis copier le paramètre 'code' depuis " + "l'URL de redirection et le passer à strava_exchange_token.", inputSchema: z.object({}), }, async () => { if (!config.clientId) { return { content: [ { type: "text", text: "Erreur : STRAVA_CLIENT_ID non configuré. Copie .env.example en .env et renseigne tes credentials.", }, ], }; } const redirectUri = config.redirectUri; const portMatch = redirectUri.match(/:(\d+)\//); const port = portMatch ? parseInt(portMatch[1], 10) : 8080; startOAuthCallbackServer(port); const url = buildAuthorizationUrl(); return { content: [ { type: "text", text: `Ouvre cette URL dans ton navigateur :\n\n${url}\n\nUne fois que tu as autorisé l'application sur Strava, la page affichera "✓ Authentification réussie !" et les tokens seront sauvegardés automatiquement. Tu n'as rien d'autre à faire.`, }, ], }; } ); - src/auth/authTools.ts:17-17 (schema)Input schema for the tool: z.object({}) - an empty object, meaning no inputs required.
inputSchema: z.object({}), - src/auth/oauth.ts:6-15 (helper)buildAuthorizationUrl() helper function that constructs the Strava OAuth2 authorization URL using client_id, redirect_uri, response_type, approval_prompt, and scope parameters.
export function buildAuthorizationUrl(): string { const params = new URLSearchParams({ client_id: config.clientId, redirect_uri: config.redirectUri, response_type: "code", approval_prompt: "force", scope: STRAVA_SCOPES, }); return `${STRAVA_AUTH_URL}?${params.toString()}`; } - src/auth/callbackServer.ts:6-63 (helper)startOAuthCallbackServer() helper function that starts an HTTP server on localhost to handle the OAuth callback from Strava after user authorizes.
export function startOAuthCallbackServer(port: number): void { if (callbackServer) return; callbackServer = http.createServer(async (req, res) => { try { const url = new URL(req.url ?? "/", `http://localhost:${port}`); if (url.pathname !== "/callback") { res.writeHead(404); res.end("Not found"); return; } const error = url.searchParams.get("error"); if (error) { res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }); res.end( `<html><body><h1>Erreur Strava</h1><p>${error}</p></body></html>` ); stopOAuthCallbackServer(); return; } const code = url.searchParams.get("code"); if (!code) { res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" }); res.end("<html><body><h1>Paramètre code manquant</h1></body></html>"); stopOAuthCallbackServer(); return; } await exchangeCodeForTokens(code); res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }); res.end(` <html><body style="font-family:sans-serif;text-align:center;padding:60px"> <h1>✓ Authentification réussie !</h1> <p>Tu peux fermer cet onglet et revenir dans Claude.</p> </body></html> `); } catch (err) { const msg = err instanceof Error ? err.message : String(err); res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" }); res.end( `<html><body><h1>Erreur lors de l'échange du token</h1><p>${msg}</p></body></html>` ); } finally { stopOAuthCallbackServer(); } }); callbackServer.listen(port, "127.0.0.1", () => { console.error(`OAuth callback server listening on http://localhost:${port}/callback`); }); callbackServer.on("error", (err) => { console.error("Callback server error:", err.message); callbackServer = null; }); }