Skip to main content
Glama

MCP Firebird

sse-json-parsing.test.js7.53 kB
/** * Tests for SSE JSON parsing bug fix * This test validates the fix for the issue where * POST requests to /messages endpoint fail to parse JSON body correctly */ describe('SSE JSON Parsing Fix', () => { describe('JSON Parsing Logic', () => { test('should parse valid JSON from text/plain content', () => { // Simulate the custom parsing logic we implemented const textBody = '{"jsonrpc":"2.0","method":"tools/list","id":1}'; let parsedBody; // This is the same logic we implemented in the middleware try { const trimmedBody = textBody.trim(); if ((trimmedBody.startsWith('{') && trimmedBody.endsWith('}')) || (trimmedBody.startsWith('[') && trimmedBody.endsWith(']'))) { parsedBody = JSON.parse(trimmedBody); } } catch { // Should not throw } expect(parsedBody).toEqual({ jsonrpc: '2.0', method: 'tools/list', id: 1 }); }); test('should handle malformed JSON gracefully', () => { const malformedJson = '{ invalid json }'; let parsedBody = malformedJson; // Simulate our error handling try { const trimmedBody = malformedJson.trim(); if ((trimmedBody.startsWith('{') && trimmedBody.endsWith('}')) || (trimmedBody.startsWith('[') && trimmedBody.endsWith(']'))) { parsedBody = JSON.parse(trimmedBody); } } catch { // Should continue with original body, not crash expect(parsedBody).toBe(malformedJson); } // Should not have crashed and should preserve original body expect(parsedBody).toBe(malformedJson); }); test('should handle array JSON correctly', () => { const arrayJson = '[{"test": "data"}, {"test2": "data2"}]'; let parsedBody; try { const trimmedBody = arrayJson.trim(); if ((trimmedBody.startsWith('{') && trimmedBody.endsWith('}')) || (trimmedBody.startsWith('[') && trimmedBody.endsWith(']'))) { parsedBody = JSON.parse(trimmedBody); } } catch { // Should not throw } expect(parsedBody).toEqual([ { test: 'data' }, { test2: 'data2' } ]); }); test('should not parse non-JSON text', () => { const plainText = 'This is just plain text'; let parsedBody = plainText; try { const trimmedBody = plainText.trim(); if ((trimmedBody.startsWith('{') && trimmedBody.endsWith('}')) || (trimmedBody.startsWith('[') && trimmedBody.endsWith(']'))) { parsedBody = JSON.parse(trimmedBody); } } catch { // Should not throw } // Should remain as original text since it doesn't look like JSON expect(parsedBody).toBe(plainText); }); }); describe('Content-Type Handling', () => { test('should identify application/json content correctly', () => { const contentTypes = [ 'application/json', 'application/json; charset=utf-8', 'APPLICATION/JSON', 'application/json;charset=UTF-8' ]; contentTypes.forEach(contentType => { expect(contentType.toLowerCase().includes('application/json')).toBe(true); }); }); test('should identify text/plain content correctly', () => { const contentTypes = [ 'text/plain', 'text/plain; charset=utf-8', 'TEXT/PLAIN', 'text/plain;charset=UTF-8' ]; contentTypes.forEach(contentType => { expect(contentType.toLowerCase().includes('text/plain')).toBe(true); }); }); test('should validate request body types', () => { // Test different body types that might be received const validBodies = [ { jsonrpc: '2.0', method: 'test', id: 1 }, [], { test: 'data' } ]; const invalidBodies = [ null, undefined, 'string', 123, true ]; validBodies.forEach(body => { expect(typeof body).toBe('object'); expect(body !== null).toBe(true); }); invalidBodies.forEach(body => { const isValidObject = body !== null && typeof body === 'object'; expect(isValidObject).toBe(false); }); }); }); describe('Bug Fix Validation', () => { test('should demonstrate the fix prevents [object Object] error', () => { // This test demonstrates that our parsing logic prevents the // "Invalid message: [object Object]" error that was reported const mockRequestBody = { jsonrpc: '2.0', method: 'tools/list', id: 1 }; // Before the fix: req.body would be [object Object] when converted to string const beforeFix = mockRequestBody.toString(); // This would be "[object Object]" expect(beforeFix).toBe('[object Object]'); // After the fix: req.body should be a proper object const afterFix = mockRequestBody; expect(typeof afterFix).toBe('object'); expect(afterFix.jsonrpc).toBe('2.0'); expect(afterFix.method).toBe('tools/list'); expect(afterFix.id).toBe(1); }); test('should handle the catch-22 scenario described in the bug report', () => { // The bug report mentioned a catch-22 where: // - application/json returns "Invalid message: [object Object]" // - text/plain returns "unsupported content-type: text/plain" // Our fix should handle both scenarios: // Scenario 1: application/json should work with proper middleware const jsonContentType = 'application/json'; expect(jsonContentType.includes('application/json')).toBe(true); // Scenario 2: text/plain should be parsed if it contains JSON const textPlainJson = '{"jsonrpc":"2.0","method":"test","id":1}'; let parsed; // Our custom parsing logic for text/plain if (textPlainJson.trim().startsWith('{') && textPlainJson.trim().endsWith('}')) { try { parsed = JSON.parse(textPlainJson); } catch { // Graceful fallback parsed = textPlainJson; } } expect(parsed).toEqual({ jsonrpc: '2.0', method: 'test', id: 1 }); }); }); });

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/PuroDelphi/mcpFirebird'

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