Skip to main content
Glama
test-server.tsβ€’17.9 kB
/** * Test script for MCP server * Uses MCP SDK Client for proper protocol handling * Following MCP best practices: https://modelcontextprotocol.io */ import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import 'dotenv/config'; // Test data constants const TEST_USERNAME = 'ravindra-adireddy'; const TEST_FROM = '2025-02-01'; const TEST_TO = '2025-12-31'; const TEST_REPOS = ['radireddy/AiApps']; // Request timeout (30 seconds) const REQUEST_TIMEOUT = 30000; // Test registry - maps test names to test functions type TestFunction = (client: Client) => Promise<void>; const testRegistry: Record<string, TestFunction> = { 'listTools': async (client) => { console.log('\nπŸ“‹ Test: List available tools'); console.log('-'.repeat(60)); try { const tools = await Promise.race([ client.listTools(), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT) ) ]) as any; console.log(`βœ… Found ${tools.tools?.length || 0} tools:`); tools.tools?.forEach((tool: any) => { console.log(` - ${tool.name}: ${tool.description?.substring(0, 80)}...`); }); } catch (error: any) { console.error('❌ Error:', error.message); } }, 'github.getAuthoredPRs': async (client) => { console.log('\nπŸ“‹ Test: Get Authored PRs'); console.log('-'.repeat(60)); console.log('Request: github.getAuthoredPRs'); console.log('Params:', JSON.stringify({ username: TEST_USERNAME, repos: TEST_REPOS, from: TEST_FROM, to: TEST_TO, }, null, 2)); console.log(`\n⚠️ Note: Testing with date range ${TEST_FROM} to ${TEST_TO}`); console.log(` If this is in the future, you may get 0 results if no PRs exist in that range.`); try { const result = await Promise.race([ client.callTool({ name: 'github.getAuthoredPRs', arguments: { username: TEST_USERNAME, repos: TEST_REPOS, from: TEST_FROM, to: TEST_TO, }, }), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT) ) ]) as any; console.log('\nβœ… Response received:'); const content = result.content?.[0]?.text; if (content) { const data = JSON.parse(content); const prCount = data.prs?.length || 0; console.log(` Found ${prCount} PRs`); if (prCount === 0) { console.log(`\n ⚠️ No PRs found. This could mean:`); console.log(` - No PRs exist for user "${TEST_USERNAME}" in repos ${TEST_REPOS.join(', ')}`); console.log(` - No PRs exist in the date range ${TEST_FROM} to ${TEST_TO}`); console.log(` - The date range is in the future and no PRs exist yet`); console.log(` - The repo names "${TEST_REPOS.join(', ')}" might be incorrect`); console.log(` - Try testing with a past date range or different repo to verify functionality`); } else { console.log('\n First PR:'); console.log(JSON.stringify(data.prs[0], null, 4)); } } else { console.log(JSON.stringify(result, null, 2)); } } catch (error: any) { console.error('❌ Error:', error.message); if (error.message.includes('authentication')) { console.error(' πŸ’‘ Make sure GITHUB_TOKEN is set in your environment'); } if (error.message.includes('Timeout')) { console.error(' πŸ’‘ Request timed out. The server may be slow or unresponsive.'); } } }, 'github.getPRReviews': async (client) => { console.log('\nπŸ“‹ Test: Get PR Reviews'); console.log('-'.repeat(60)); try { const result = await Promise.race([ client.callTool({ name: 'github.getPRReviews', arguments: { username: TEST_USERNAME, repos: TEST_REPOS, from: TEST_FROM, to: TEST_TO, }, }), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT) ) ]) as any; console.log('\nβœ… Response received:'); const content = result.content?.[0]?.text; if (content) { const data = JSON.parse(content); console.log(` Found ${data.reviews?.length || 0} reviews`); if (data.reviews && data.reviews.length > 0) { console.log('\n First review:'); console.log(JSON.stringify(data.reviews[0], null, 4)); } } } catch (error: any) { console.error('❌ Error:', error.message); } }, 'github.getReviewComments': async (client) => { console.log('\nπŸ“‹ Test: Get Review Comments'); console.log('-'.repeat(60)); try { const result = await Promise.race([ client.callTool({ name: 'github.getReviewComments', arguments: { username: TEST_USERNAME, repos: TEST_REPOS, from: TEST_FROM, to: TEST_TO, }, }), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT) ) ]) as any; console.log('\nβœ… Response received:'); const content = result.content?.[0]?.text; if (content) { const data = JSON.parse(content); console.log(`\n πŸ“Š Summary:`); console.log(` User ID: ${data.userId}`); console.log(` Date Range: ${data.dateRange?.from} to ${data.dateRange?.to}`); console.log(` Total PRs Reviewed: ${data.totalPRsReviewed}`); console.log(` Total Comments: ${data.totalComments}`); if (data.totalPRsReviewed === 0) { console.log(`\n ⚠️ No PRs reviewed. This could mean:`); console.log(` - No review comments exist for user "${TEST_USERNAME}"`); console.log(` - No comments exist in the date range ${TEST_FROM} to ${TEST_TO}`); console.log(` - The date range is in the future and no comments exist yet`); } else { console.log(`\n πŸ“ PR Details (showing first PR):`); if (data.prs && data.prs.length > 0) { const firstPR = data.prs[0]; console.log(` PR #${firstPR.prNumber}: ${firstPR.prTitle}`); console.log(` Repository: ${firstPR.prRepo}`); console.log(` PR Created At: ${firstPR.prCreatedAt || 'N/A'}`); console.log(` Comments in this PR: ${firstPR.totalComments}`); if (firstPR.comments && firstPR.comments.length > 0) { const firstComment = firstPR.comments[0].replace(/\n/g, '\\n').substring(0, 100); console.log(` First comment: "${firstComment}${firstPR.comments[0].length > 100 ? '...' : ''}"`); } } } } } catch (error: any) { console.error('❌ Error:', error.message); } }, 'github.getCommentImpact': async (client) => { console.log('\nπŸ“‹ Test: Get Comment Impact'); console.log('-'.repeat(60)); try { const result = await Promise.race([ client.callTool({ name: 'github.getCommentImpact', arguments: { username: TEST_USERNAME, repos: TEST_REPOS, from: TEST_FROM, to: TEST_TO, }, }), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT) ) ]) as any; console.log('\nβœ… Response received:'); const content = result.content?.[0]?.text; if (content) { const data = JSON.parse(content); console.log(` Found ${data.impacts?.length || 0} comment impacts`); if (data.impacts && data.impacts.length > 0) { console.log('\n First impact:'); console.log(JSON.stringify(data.impacts[0], null, 4)); } } } catch (error: any) { console.error('❌ Error:', error.message); } }, 'github.getUserComments': async (client) => { console.log('\nπŸ“‹ Test: Get User Comments'); console.log('-'.repeat(60)); console.log('Request: github.getUserComments'); console.log('Params:', JSON.stringify({ username: TEST_USERNAME, repos: TEST_REPOS, from: TEST_FROM, to: TEST_TO, }, null, 2)); console.log(`\n⚠️ Note: Testing with date range ${TEST_FROM} to ${TEST_TO}`); console.log(` If this is in the future, you may get 0 results if no comments exist in that range.`); try { const result = await Promise.race([ client.callTool({ name: 'github.getUserComments', arguments: { username: TEST_USERNAME, repos: TEST_REPOS, from: TEST_FROM, to: TEST_TO, }, }), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT) ) ]) as any; console.log('\nβœ… Response received:'); const content = result.content?.[0]?.text; if (content) { const data = JSON.parse(content); const commentCount = data.comments?.length || 0; console.log(` Found ${commentCount} comments`); if (commentCount === 0) { console.log(`\n ⚠️ No comments found. This could mean:`); console.log(` - No comments exist for user "${TEST_USERNAME}" in repos ${TEST_REPOS.join(', ')}`); console.log(` - No comments exist in the date range ${TEST_FROM} to ${TEST_TO}`); console.log(` - The date range is in the future and no comments exist yet`); console.log(` - The repo names "${TEST_REPOS.join(', ')}" might be incorrect`); console.log(` - Try testing with a past date range or different repo to verify functionality`); } else { console.log('\n First comment:'); console.log(JSON.stringify(data.comments[0], null, 4)); // Show comment type breakdown const reviewComments = data.comments.filter((c: any) => c.commentType === 'review').length; const issueComments = data.comments.filter((c: any) => c.commentType === 'issue').length; console.log(`\n Comment breakdown:`); console.log(` - Review comments: ${reviewComments}`); console.log(` - Issue comments: ${issueComments}`); } } else { console.log(JSON.stringify(result, null, 2)); } } catch (error: any) { console.error('❌ Error:', error.message); if (error.message.includes('authentication')) { console.error(' πŸ’‘ Make sure GITHUB_TOKEN is set in your environment'); } if (error.message.includes('Invalid repository format')) { console.error(' πŸ’‘ Repository format should be "owner/repo" (e.g., "UiPath/business-apps-jamjam")'); } if (error.message.includes('Timeout')) { console.error(' πŸ’‘ Request timed out. The server may be slow or unresponsive.'); } } }, 'github.getUserRepoStats': async (client) => { console.log('\nπŸ“‹ Test: Get User Repository Statistics'); console.log('-'.repeat(60)); console.log('Request: github.getUserRepoStats'); console.log('Params:', JSON.stringify({ username: TEST_USERNAME, repos: TEST_REPOS, from: TEST_FROM, to: TEST_TO, }, null, 2)); console.log(`\n⚠️ Note: Testing with date range ${TEST_FROM} to ${TEST_TO}`); console.log(` This tool aggregates statistics from multiple sources.`); try { const result = await Promise.race([ client.callTool({ name: 'github.getUserRepoStats', arguments: { username: TEST_USERNAME, repos: TEST_REPOS, from: TEST_FROM, to: TEST_TO, }, }), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), REQUEST_TIMEOUT) ) ]) as any; console.log('\nβœ… Response received:'); const content = result.content?.[0]?.text; if (content) { const data = JSON.parse(content); const stats = data.stats; if (stats) { console.log('\n πŸ“Š Repository Statistics:'); console.log(` Username: ${stats.username}`); console.log(` Repository: ${stats.repo}`); console.log(` Time Range: ${stats.timeRange.from} to ${stats.timeRange.to}`); console.log(`\n πŸ“ Pull Requests:`); console.log(` Total: ${stats.prs.count}`); console.log(` Merged: ${stats.prs.merged}`); console.log(` Open: ${stats.prs.open}`); console.log(` Closed: ${stats.prs.closed}`); console.log(`\n πŸ’¬ Comments:`); console.log(` Total: ${stats.comments.total}`); console.log(` Review: ${stats.comments.review}`); console.log(` Issue: ${stats.comments.issue}`); console.log(`\n πŸ‘€ Reviews:`); console.log(` Total: ${stats.reviews.total}`); console.log(` Approved: ${stats.reviews.approved}`); console.log(` Changes Requested: ${stats.reviews.changesRequested}`); console.log(` Commented: ${stats.reviews.commented}`); console.log(`\n πŸ“ˆ Code Changes:`); console.log(` Files Changed: ${stats.codeChanges.filesChanged}`); console.log(` Additions: ${stats.codeChanges.additions} lines`); console.log(` Deletions: ${stats.codeChanges.deletions} lines`); console.log(` Net Change: ${stats.codeChanges.netChange} lines`); if (stats.prs.count === 0 && stats.comments.total === 0 && stats.reviews.total === 0) { console.log(`\n ⚠️ No activity found. This could mean:`); console.log(` - No activity exists for user "${TEST_USERNAME}" in repos ${TEST_REPOS.join(', ')}`); console.log(` - No activity exists in the date range ${TEST_FROM} to ${TEST_TO}`); console.log(` - The date range is in the future and no activity exists yet`); console.log(` - The repo names "${TEST_REPOS.join(', ')}" might be incorrect`); } } else { console.log(JSON.stringify(data, null, 2)); } } else { console.log(JSON.stringify(result, null, 2)); } } catch (error: any) { console.error('❌ Error:', error.message); if (error.message.includes('authentication')) { console.error(' πŸ’‘ Make sure GITHUB_TOKEN is set in your environment'); } if (error.message.includes('Invalid repository format')) { console.error(' πŸ’‘ Repository format should be "owner/repo" (e.g., "UiPath/business-apps-jamjam")'); } if (error.message.includes('Timeout')) { console.error(' πŸ’‘ Request timed out. The server may be slow or unresponsive.'); } } }, }; function parseTestArgs(): string[] { const args = process.argv.slice(2); if (args.length === 0) { // No arguments - run all tests return Object.keys(testRegistry); } // Parse arguments - support comma-separated or space-separated const testNames: string[] = []; for (const arg of args) { if (arg.includes(',')) { testNames.push(...arg.split(',').map(t => t.trim())); } else { testNames.push(arg.trim()); } } return testNames; } function printAvailableTests() { console.log('\nπŸ“‹ Available tests:'); console.log('-'.repeat(60)); Object.keys(testRegistry).forEach(testName => { console.log(` - ${testName}`); }); console.log(''); } async function runTests() { // Check for GITHUB_TOKEN if (!process.env.GITHUB_TOKEN) { console.error('❌ Error: GITHUB_TOKEN is required'); console.error(' Set it in .env file: GITHUB_TOKEN=your_token_here'); console.error(' Or as environment variable: export GITHUB_TOKEN=your_token_here'); process.exit(1); } const testNames = parseTestArgs(); // Validate test names const invalidTests = testNames.filter(name => !testRegistry[name]); if (invalidTests.length > 0) { console.error(`\n❌ Invalid test names: ${invalidTests.join(', ')}`); printAvailableTests(); process.exit(1); } // Create MCP client with stdio transport const transport = new StdioClientTransport({ command: 'node', args: ['dist/mcp/server.js'], env: { ...process.env, GITHUB_TOKEN: process.env.GITHUB_TOKEN, }, }); const client = new Client( { name: 'github-mcp-test-client', version: '1.0.0', }, { capabilities: {}, } ); try { // Connect to server await client.connect(transport); console.log('βœ… MCP Client connected to server\n'); console.log('πŸ§ͺ Testing MCP Server\n'); console.log('='.repeat(60)); // Show which tests will run if (testNames.length === Object.keys(testRegistry).length) { console.log(`\nπŸ“‹ Running all ${testNames.length} tests\n`); } else { console.log(`\nπŸ“‹ Running ${testNames.length} selected test(s): ${testNames.join(', ')}\n`); } // Run selected tests for (const testName of testNames) { await testRegistry[testName](client); } console.log('\n' + '='.repeat(60)); console.log(`βœ… ${testNames.length} test(s) completed!\n`); } catch (error: any) { console.error('❌ Test failed:', error); process.exit(1); } finally { await client.close(); console.log('πŸ›‘ Client disconnected'); } } // Run tests runTests().catch(console.error);

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/radireddy/github-mcp'

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