Skip to main content
Glama

MCP Firebird

sse-json-parsing.test.ts7.59 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('Middleware Configuration', () => { test('should handle JSON parsing middleware setup', () => { // Create a mock request to test middleware behavior const mockReq = { headers: { 'content-type': 'application/json' }, body: { test: 'data' }, method: 'POST', url: '/messages' }; // This test validates that our middleware setup doesn't crash // The actual parsing is handled by Express internally expect(() => { // Simulate middleware execution if (mockReq.headers['content-type']?.includes('application/json')) { expect(typeof mockReq.body).toBe('object'); } }).not.toThrow(); }); test('should handle text/plain content type parsing', () => { // Test the custom middleware logic for text/plain -> JSON conversion const textBody = '{"jsonrpc":"2.0","method":"tools/list","id":1}'; // Simulate our custom parsing logic let parsedBody; 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 }'; // Simulate our error handling let parsedBody = malformedJson; 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); }); }); 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); }); }); }); });

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