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);
});
}