Skip to main content
Glama
get-access-token.js5.86 kB
#!/usr/bin/env node import express from 'express'; import axios from 'axios'; import open from 'open'; import { randomBytes } from 'crypto'; import dotenv from 'dotenv'; // Load environment variables from .env file dotenv.config(); // Configuration const CLIENT_ID = process.env.CLICKUP_CLIENT_ID; const CLIENT_SECRET = process.env.CLICKUP_CLIENT_SECRET; const REDIRECT_URI = 'http://localhost:3000/auth/callback'; const PORT = 3000; // Validate configuration if (!CLIENT_ID || !CLIENT_SECRET) { console.error('Error: CLICKUP_CLIENT_ID and CLICKUP_CLIENT_SECRET environment variables are required.'); console.error('Please create a .env file with these values or set them in your environment.'); console.error('You can obtain these values by creating an app at https://clickup.com/api/developer/'); process.exit(1); } // Generate a random state for CSRF protection const state = randomBytes(16).toString('hex'); // Create Express app const app = express(); // Home route app.get('/', (req, res) => { res.send(` <html> <head> <title>ClickUp OAuth Setup</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } .button { display: inline-block; background-color: #7B68EE; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px; margin-top: 20px; } </style> </head> <body> <h1>ClickUp OAuth Setup</h1> <p>Click the button below to authorize the ClickUp MCP server to access your ClickUp account.</p> <a href="/auth" class="button">Authorize with ClickUp</a> </body> </html> `); }); // Auth route - redirect to ClickUp OAuth page app.get('/auth', (req, res) => { const authUrl = `https://app.clickup.com/api?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&state=${state}`; res.redirect(authUrl); }); // Callback route - handle OAuth callback app.get('/auth/callback', async (req, res) => { const { code, state: returnedState } = req.query; // Verify state to prevent CSRF attacks if (returnedState !== state) { return res.status(400).send('Invalid state parameter. Possible CSRF attack.'); } if (!code) { return res.status(400).send('Authorization code not received.'); } try { // Exchange code for access token const response = await axios.post('https://api.clickup.com/api/v2/oauth/token', { client_id: CLIENT_ID, client_secret: CLIENT_SECRET, code, grant_type: 'authorization_code', redirect_uri: REDIRECT_URI, }); const { access_token } = response.data; // Display the access token res.send(` <html> <head> <title>ClickUp OAuth Setup - Success</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } .token-box { background-color: #f0f0f0; padding: 15px; border-radius: 5px; font-family: monospace; word-break: break-all; margin: 20px 0; } .instructions { background-color: #e6f7ff; padding: 15px; border-radius: 5px; margin: 20px 0; } </style> </head> <body> <h1>Authorization Successful!</h1> <p>Your ClickUp access token has been generated successfully.</p> <h2>Your Access Token:</h2> <div class="token-box">${access_token}</div> <div class="instructions"> <h3>Next Steps:</h3> <ol> <li>Copy the access token above.</li> <li>Add it to your MCP settings file as the <code>CLICKUP_API_TOKEN</code> environment variable.</li> <li>You can now close this window and use the ClickUp MCP server.</li> </ol> </div> <p><strong>Note:</strong> Keep this token secure. It provides access to your ClickUp account.</p> </body> </html> `); // Also log the token to the console for easy copying console.log('\n==== ClickUp Access Token ===='); console.log(access_token); console.log('=============================\n'); console.log('Add this token to your MCP settings file as the CLICKUP_API_TOKEN environment variable.'); // Automatically close the server after 2 minutes setTimeout(() => { server.close(() => { console.log('OAuth server closed.'); process.exit(0); }); }, 120000); } catch (error) { console.error('Error exchanging code for access token:', error.response?.data || error.message); res.status(500).send(` <html> <head> <title>ClickUp OAuth Setup - Error</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; } .error { background-color: #ffebee; padding: 15px; border-radius: 5px; margin: 20px 0; } </style> </head> <body> <h1>Authorization Error</h1> <div class="error"> <p>An error occurred while trying to get your access token:</p> <pre>${error.response?.data ? JSON.stringify(error.response.data, null, 2) : error.message}</pre> </div> <p>Please try again or check your client ID and secret.</p> </body> </html> `); } }); // Start the server const server = app.listen(PORT, () => { console.log(`OAuth server running at http://localhost:${PORT}`); console.log('Opening browser for authorization...'); // Open the browser to start the OAuth flow open(`http://localhost:${PORT}`); }); // Handle server shutdown process.on('SIGINT', () => { server.close(() => { console.log('OAuth server closed.'); process.exit(0); }); });

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/nsxdavid/clickup-mcp-server'

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