Skip to main content
Glama
test.js3.69 kB
import http from 'k6/http'; import { check, sleep } from 'k6'; import { Rate } from 'k6/metrics'; // Custom metrics export const errorRate = new Rate('errors'); // Test configuration export const options = { stages: [ { duration: '2m', target: 100 }, // Ramp up to 100 users { duration: '5m', target: 100 }, // Stay at 100 users { duration: '2m', target: 200 }, // Ramp up to 200 users { duration: '5m', target: 200 }, // Stay at 200 users { duration: '2m', target: 0 }, // Ramp down ], thresholds: { 'http_req_duration': ['p(95)<200'], // 95% of requests must complete below 200ms 'errors': ['rate<0.01'], // Error rate must be below 1% }, }; const BASE_URL = 'http://localhost:8123'; const AUTH_TOKEN = 'test-token'; const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${AUTH_TOKEN}`, }; export default function () { const scenarios = [ testHealthCheck, testMCPInitialize, testToolsList, testResourcesList, ]; // Randomly select a scenario const scenario = scenarios[Math.floor(Math.random() * scenarios.length)]; scenario(); sleep(1); } function testHealthCheck() { const response = http.get(`${BASE_URL}/healthz`); const result = check(response, { 'health check status is 200': (r) => r.status === 200, 'health check response time < 50ms': (r) => r.timings.duration < 50, }); errorRate.add(!result); } function testMCPInitialize() { const payload = JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'k6-load-test', version: '1.0.0', }, }, }); const response = http.post(`${BASE_URL}/mcp`, payload, { headers }); const result = check(response, { 'initialize status is 200': (r) => r.status === 200, 'initialize has jsonrpc field': (r) => { try { return JSON.parse(r.body).jsonrpc === '2.0'; } catch { return false; } }, 'initialize response time < 100ms': (r) => r.timings.duration < 100, }); errorRate.add(!result); } function testToolsList() { const payload = JSON.stringify({ jsonrpc: '2.0', id: 2, method: 'tools/list', }); const response = http.post(`${BASE_URL}/mcp`, payload, { headers }); const result = check(response, { 'tools/list status is 200': (r) => r.status === 200, 'tools/list has tools': (r) => { try { const body = JSON.parse(r.body); return body.result && Array.isArray(body.result.tools); } catch { return false; } }, 'tools/list response time < 100ms': (r) => r.timings.duration < 100, }); errorRate.add(!result); } function testResourcesList() { const payload = JSON.stringify({ jsonrpc: '2.0', id: 3, method: 'resources/list', params: { uri: 'teamcity://projects', }, }); const response = http.post(`${BASE_URL}/mcp`, payload, { headers }); const result = check(response, { 'resources/list status is 200': (r) => r.status === 200, 'resources/list has resources': (r) => { try { const body = JSON.parse(r.body); return body.result && Array.isArray(body.result.resources); } catch { return false; } }, 'resources/list response time < 200ms': (r) => r.timings.duration < 200, }); errorRate.add(!result); } export function setup() { console.log('Starting load test...'); // Could add setup code here (e.g., warming up the server) } export function teardown() { console.log('Load test completed.'); // Could add cleanup code here }

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/itcaat/teamcity-mcp'

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