Skip to main content
Glama

Oura Ring MCP Server

by JamesLouie
manual-test.tsโ€ข7.87 kB
#!/usr/bin/env node import { OuraClient } from '../src/oura-client.js'; import dotenv from 'dotenv'; // Load environment variables dotenv.config(); async function manualTest() { console.log('๐Ÿงช Manual Testing Oura Ring API Connection...\n'); // Check if access token is available const accessToken = process.env.OURA_ACCESS_TOKEN; if (!accessToken) { console.error('โŒ OURA_ACCESS_TOKEN environment variable is required'); console.log('๐Ÿ“ Please create a .env file with:'); console.log('OURA_ACCESS_TOKEN=your_personal_access_token_here'); console.log('\nGet your token from: https://cloud.ouraring.com/personal-access-tokens'); process.exit(1); } console.log('โœ… Access token found'); try { // Initialize Oura client const ouraClient = new OuraClient({ accessToken, clientId: process.env.OURA_CLIENT_ID, clientSecret: process.env.OURA_CLIENT_SECRET, }); console.log('๐Ÿ”— Oura client initialized\n'); // Test 1: Get personal info console.log('๐Ÿ‘ค Testing Personal Info...'); try { const personalInfo = await ouraClient.getPersonalInfo(); console.log('โœ… Personal info retrieved successfully!'); // Handle the union type for PersonalInfoResponse const data = 'data' in personalInfo ? personalInfo.data : personalInfo; console.log(` ๐Ÿ“ง Email: ${data.email || 'N/A'}`); console.log(` ๐ŸŽ‚ Age: ${data.age || 'N/A'}`); console.log(` โš–๏ธ Weight: ${data.weight || 'N/A'} kg`); console.log(` ๐Ÿ“ Height: ${data.height || 'N/A'} cm`); console.log(` ๐Ÿงฌ Biological Sex: ${data.biological_sex || 'N/A'}`); console.log(` ๐ŸŒ Timezone: ${data.timezone || 'N/A'}`); } catch (error) { console.log('โŒ Personal info failed:', (error as Error).message); } // Test 2: Get recent sleep data console.log('\n๐Ÿ˜ด Testing Sleep Data (last 7 days)...'); try { const endDate = new Date().toISOString().split('T')[0]; const startDate = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]; const sleepData = await ouraClient.getDailySleep({ start_date: startDate, end_date: endDate, }); console.log('โœ… Sleep data retrieved successfully!'); console.log(` ๐Ÿ“Š Found ${sleepData.data.length} sleep records`); if (sleepData.data.length > 0) { const latest = sleepData.data[sleepData.data.length - 1]; console.log(` ๐ŸŒ™ Latest sleep score: ${latest.score || 'N/A'}`); console.log(` ๐Ÿ“… Date: ${latest.day}`); if (latest.contributors) { console.log(` ๐Ÿƒ Contributors:`); console.log(` Deep Sleep: ${latest.contributors.deep_sleep || 'N/A'}`); console.log(` Efficiency: ${latest.contributors.efficiency || 'N/A'}`); console.log(` Latency: ${latest.contributors.latency || 'N/A'}`); console.log(` REM Sleep: ${latest.contributors.rem_sleep || 'N/A'}`); } } else { console.log(' โ„น๏ธ No sleep data found - try syncing your Oura app'); } } catch (error) { console.log('โŒ Sleep data failed:', (error as Error).message); } // Test 3: Get recent activity data console.log('\n๐Ÿƒ Testing Activity Data (last 3 days)...'); try { const endDate = new Date().toISOString().split('T')[0]; const startDate = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]; const activityData = await ouraClient.getDailyActivity({ start_date: startDate, end_date: endDate, }); console.log('โœ… Activity data retrieved successfully!'); console.log(` ๐Ÿ“Š Found ${activityData.data.length} activity records`); if (activityData.data.length > 0) { const latest = activityData.data[activityData.data.length - 1]; console.log(` ๐ŸŽฏ Latest activity score: ${latest.score || 'N/A'}`); console.log(` ๐Ÿ‘Ÿ Steps: ${latest.steps?.toLocaleString() || 'N/A'}`); console.log(` ๐Ÿ”ฅ Active calories: ${latest.active_calories || 'N/A'}`); console.log(` ๐Ÿ’ช Total calories: ${latest.total_calories || 'N/A'}`); console.log(` ๐Ÿ“… Date: ${latest.day}`); } else { console.log(' โ„น๏ธ No activity data found'); } } catch (error) { console.log('โŒ Activity data failed:', (error as Error).message); } // Test 4: Get readiness data console.log('\n๐ŸŽฏ Testing Readiness Data (last 3 days)...'); try { const endDate = new Date().toISOString().split('T')[0]; const startDate = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]; const readinessData = await ouraClient.getDailyReadiness({ start_date: startDate, end_date: endDate, }); console.log('โœ… Readiness data retrieved successfully!'); console.log(` ๐Ÿ“Š Found ${readinessData.data.length} readiness records`); if (readinessData.data.length > 0) { const latest = readinessData.data[readinessData.data.length - 1]; console.log(` ๐Ÿ’ช Latest readiness score: ${latest.score || 'N/A'}`); console.log(` ๐ŸŒก๏ธ Temperature deviation: ${latest.temperature_deviation || 'N/A'}ยฐC`); console.log(` ๐Ÿ“… Date: ${latest.day}`); if (latest.contributors) { console.log(` ๐Ÿ”ง Contributors:`); console.log(` Activity Balance: ${latest.contributors.activity_balance || 'N/A'}`); console.log(` HRV Balance: ${latest.contributors.hrv_balance || 'N/A'}`); console.log(` Sleep Balance: ${latest.contributors.sleep_balance || 'N/A'}`); } } else { console.log(' โ„น๏ธ No readiness data found'); } } catch (error) { console.log('โŒ Readiness data failed:', (error as Error).message); } // Test 5: Test webhook subscriptions (if client credentials available) if (process.env.OURA_CLIENT_ID && process.env.OURA_CLIENT_SECRET) { console.log('\n๐Ÿ”— Testing Webhook Subscriptions...'); try { const webhooks = await ouraClient.getWebhookSubscriptions(); console.log('โœ… Webhook subscriptions retrieved successfully!'); console.log(` ๐Ÿ“Š Found ${webhooks.data.length} webhook subscriptions`); webhooks.data.forEach((webhook, index) => { console.log(` ${index + 1}. ${webhook.data_type} (${webhook.event_type}) -> ${webhook.callback_url}`); }); } catch (error) { console.log('โŒ Webhook subscriptions failed:', (error as Error).message); } } else { console.log('\n๐Ÿ”— Webhook testing skipped (OURA_CLIENT_ID and OURA_CLIENT_SECRET not set)'); } console.log('\n๐ŸŽ‰ Manual testing completed!'); console.log('\n๐Ÿ“ Next steps:'); console.log('1. The API connection is working โœ…'); console.log('2. You can now use: npm start (to start the MCP server)'); console.log('3. Configure your MCP client with the config.example.json'); console.log('4. Your MCP client can now call any of the 19 available tools!'); console.log('\n๐Ÿ’ก Pro tips:'); console.log('- Sleep data requires opening the Oura app to sync'); console.log('- Activity data may sync automatically in the background'); console.log('- Try different date ranges to find more data'); console.log('- Use webhooks for real-time updates (requires OAuth app setup)'); } catch (error) { console.error('โŒ Manual test failed:', error); process.exit(1); } } if (import.meta.url === `file://${process.argv[1]}`) { manualTest().catch((error) => { console.error('Fatal error:', error); process.exit(1); }); }

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/JamesLouie/oura-ring-mcp'

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