Files
zeekay 7e0448f10e feat: implement unified MCP search with OpenAI spec compliance and CI
## Core Implementation
- Unified search engine with strategy pattern for extensible search types
- Full OpenAI MCP specification compliance for search and fetch tools
- Multi-modal search strategies: Symbol, AST, Vector, Text, and File search
- Automatic strategy selection based on query characteristics

## Security & Remote Access
- Secure ngrok tunnel integration with automatic detection
- Multi-method authentication (Bearer token, API keys, JWT)
- Post-quantum TLS configuration support
- Rate limiting and CORS protection
- Access logging and monitoring
- Only exposes files when ngrok credentials are present

## Testing & CI
- 102 tests with 85% coverage on critical paths
- GitHub Actions CI workflow for automated testing
- Node.js 18.x and 20.x compatibility testing
- Coverage reporting to Codecov
- Security audit checks

## Documentation
- Comprehensive documentation in LLM.md
- Security guide in docs/SECURITY.md
- .npmrc excluded from repository for security

This implementation provides a production-ready search system for AI tools like ChatGPT and Claude Desktop.
2025-09-14 18:11:10 -05:00

74 lines
2.5 KiB
TypeScript

/**
* Basic tests for MCP Search implementation
* Validates core functionality and OpenAI spec compliance
*/
import { describe, it, expect, beforeEach, jest } from '@jest/globals';
import { executeSearch, executeFetch } from '../../src/search/index.js';
describe('MCP Search Basic Tests', () => {
beforeEach(() => {
// Clear environment for clean testing
delete process.env.NGROK_API_KEY;
delete process.env.NGROK_AUTHTOKEN;
});
describe('Search Functionality', () => {
it('should return results in OpenAI MCP format', async () => {
const response = await executeSearch('test');
expect(response).toHaveProperty('content');
expect(Array.isArray(response.content)).toBe(true);
expect(response.content[0]).toHaveProperty('type', 'text');
const results = JSON.parse(response.content[0].text);
expect(results).toHaveProperty('results');
expect(Array.isArray(results.results)).toBe(true);
});
it('should handle search with options', async () => {
const response = await executeSearch('test', {
maxResults: 5,
filePattern: '*.ts'
});
const results = JSON.parse(response.content[0].text);
expect(results).toHaveProperty('results');
});
});
describe('Fetch Functionality', () => {
it('should return document in OpenAI MCP format', async () => {
const response = await executeFetch('test/file.ts:10');
expect(response).toHaveProperty('content');
expect(Array.isArray(response.content)).toBe(true);
const document = JSON.parse(response.content[0].text);
expect(document).toHaveProperty('id');
expect(document).toHaveProperty('title');
expect(document).toHaveProperty('text');
expect(document).toHaveProperty('url');
expect(document).toHaveProperty('metadata');
});
});
describe('Error Handling', () => {
it('should handle search errors gracefully', async () => {
const response = await executeSearch('');
const results = JSON.parse(response.content[0].text);
expect(results).toHaveProperty('results');
expect(Array.isArray(results.results)).toBe(true);
});
it('should handle fetch errors gracefully', async () => {
const response = await executeFetch('nonexistent');
const document = JSON.parse(response.content[0].text);
expect(document).toHaveProperty('id');
expect(document).toHaveProperty('title');
expect(document).toHaveProperty('text');
});
});
});