Skip to main content
Glama
timeframe-search-validation.e2e.test.tsβ€’9.08 kB
/** * MCP Test Client validation for timeframe search functionality * Tests the real MCP tool calls to validate our fixes for Issue #523 */ import { describe, it, beforeAll, afterAll, expect } from 'vitest'; import { MCPTestClient } from 'mcp-test-client'; import type { ToolResult } from '@modelcontextprotocol/sdk/types.js'; describe('Timeframe Search MCP Tool Validation', () => { let client: MCPTestClient; beforeAll(async () => { // Point to our built MCP server client = new MCPTestClient({ serverCommand: 'node', serverArgs: ['./dist/index.js'], }); await client.init(); }); afterAll(async () => { await client.cleanup(); }); describe('Tool Discovery', () => { it('should list search-records tool', async () => { const tools = await client.listTools(); const searchTool = tools.find((tool) => tool.name === 'search-records'); expect(searchTool).toBeDefined(); expect(searchTool?.description).toContain('search'); }); }); describe('Basic Timeframe Search Tests', () => { it('should handle yesterday timeframe search for companies', async () => { await client.assertToolCall( 'search-records', { resource_type: 'companies', search_type: 'timeframe', timeframe_attribute: 'created_at', timeframe: 'yesterday', limit: 5, }, (result: ToolResult) => { console.log( 'Yesterday companies result:', JSON.stringify(result, null, 2) ); // Should not error with "Invalid condition" or "Unknown object slug" expect(result.isError).toBeFalsy(); if (result.content && result.content.length > 0) { const content = result.content[0]; if ('text' in content) { // Should not contain error messages about invalid operators expect(content.text).not.toContain('Invalid condition'); expect(content.text).not.toContain('Unknown object slug'); expect(content.text).not.toContain('greater_than_or_equal_to'); expect(content.text).not.toContain("Invalid field 'gte'"); } } } ); }); it('should handle last_7_days timeframe search for people', async () => { await client.assertToolCall( 'search-records', { resource_type: 'people', search_type: 'timeframe', timeframe_attribute: 'created_at', timeframe: 'last_7_days', limit: 5, }, (result: ToolResult) => { console.log( 'Last 7 days people result:', JSON.stringify(result, null, 2) ); // Should use Query API automatically and not error expect(result.isError).toBeFalsy(); if (result.content && result.content.length > 0) { const content = result.content[0]; if ('text' in content) { // Should not contain Advanced Search API errors expect(content.text).not.toContain('Invalid condition'); expect(content.text).not.toContain('greater_than_or_equal_to'); } } } ); }); it('should handle custom date range search for tasks', async () => { await client.assertToolCall( 'search-records', { resource_type: 'tasks', search_type: 'timeframe', timeframe_attribute: 'created_at', start_date: '2024-06-01', end_date: '2024-06-30', date_operator: 'between', limit: 5, }, (result: ToolResult) => { console.log( 'Custom date range tasks result:', JSON.stringify(result, null, 2) ); // Should use proper $gte/$lte operators expect(result.isError).toBeFalsy(); if (result.content && result.content.length > 0) { const content = result.content[0]; if ('text' in content) { // Should not contain timestamp operator errors expect(content.text).not.toContain("Invalid field 'gte'"); expect(content.text).not.toContain("Invalid field 'lte'"); } } } ); }); it('should handle single date comparison with greater_than', async () => { await client.assertToolCall( 'search-records', { resource_type: 'companies', search_type: 'timeframe', timeframe_attribute: 'created_at', start_date: '2024-07-01', date_operator: 'greater_than', limit: 5, }, (result: ToolResult) => { console.log( 'Greater than comparison result:', JSON.stringify(result, null, 2) ); // Should use $gt operator correctly expect(result.isError).toBeFalsy(); if (result.content && result.content.length > 0) { const content = result.content[0]; if ('text' in content) { expect(content.text).not.toContain("Invalid field 'gt'"); expect(content.text).not.toContain('Unknown object slug'); } } } ); }); it('should handle single date comparison with less_than', async () => { await client.assertToolCall( 'search-records', { resource_type: 'people', search_type: 'timeframe', timeframe_attribute: 'last_interaction', end_date: '2024-05-01', date_operator: 'less_than', limit: 5, }, (result: ToolResult) => { console.log( 'Less than comparison result:', JSON.stringify(result, null, 2) ); // Should use $lt operator correctly expect(result.isError).toBeFalsy(); if (result.content && result.content.length > 0) { const content = result.content[0]; if ('text' in content) { expect(content.text).not.toContain("Invalid field 'lt'"); expect(content.text).not.toContain('Unknown attribute slug'); } } } ); }); }); describe('Error Handling Validation', () => { it('should handle invalid date formats gracefully', async () => { await client.assertToolCall( 'search-records', { resource_type: 'companies', search_type: 'timeframe', timeframe_attribute: 'created_at', start_date: 'invalid-date', date_operator: 'greater_than', limit: 5, }, (result: ToolResult) => { console.log( 'Invalid date format result:', JSON.stringify(result, null, 2) ); // Should either handle gracefully or provide clear error if (result.isError) { expect(result.content[0]).toHaveProperty('text'); if ('text' in result.content[0]) { // Should not be the old API structure errors expect(result.content[0].text).not.toContain( 'Unknown object slug: c' ); expect(result.content[0].text).not.toContain( "Invalid condition 'greater_than_or_equal_to'" ); } } } ); }); it('should handle missing required parameters', async () => { await client.assertToolCall( 'search-records', { resource_type: 'companies', search_type: 'timeframe', // Missing timeframe_attribute, dates, etc. limit: 5, }, (result: ToolResult) => { console.log( 'Missing parameters result:', JSON.stringify(result, null, 2) ); // Should provide clear validation error if (result.isError && result.content && result.content.length > 0) { const content = result.content[0]; if ('text' in content) { expect(content.text).toContain('timeframe_attribute'); } } } ); }); }); describe('API Structure Validation', () => { it('should verify Query API is used for timeframe searches', async () => { // This test just ensures no structure errors occur // The actual API calls will show in logs if Query API is used correctly await client.assertToolCall( 'search-records', { resource_type: 'companies', search_type: 'timeframe', timeframe_attribute: 'updated_at', timeframe: 'last_30_days', limit: 3, }, (result: ToolResult) => { console.log( 'API structure validation result:', JSON.stringify(result, null, 2) ); // Main goal: no "Unknown object slug" or constraint format errors expect(result.isError).toBeFalsy(); } ); }); }); });

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/kesslerio/attio-mcp-server'

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