Skip to main content
Glama

Simple TypeScript MCP Server

by jasonkneen
server.test.ts7.76 kB
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'; import { NotesStore } from './notes-store.js'; // Mock the notes store vi.mock('./notes-store.js', () => { const mockStore = { getNote: vi.fn(), getAllNotes: vi.fn(), createNote: vi.fn(), updateNote: vi.fn(), deleteNote: vi.fn() }; return { NotesStore: vi.fn().mockImplementation(() => mockStore), notesStore: mockStore }; }); // Import the mocked notesStore import { notesStore } from './notes-store.js'; describe('Notes Store', () => { const mockNotes = { 'note1': { id: 'note1', title: 'Sample Note 1', content: 'This is a sample note content.', createdAt: '2025-01-01T00:00:00.000Z' }, 'note2': { id: 'note2', title: 'Sample Note 2', content: 'This is another sample note.', createdAt: '2025-01-02T00:00:00.000Z' } }; beforeEach(() => { // Reset all mocks before each test vi.resetAllMocks(); }); describe('getNote', () => { it('should return a note when given a valid ID', () => { // Setup vi.mocked(notesStore.getNote).mockReturnValue(mockNotes.note1); // Execute const result = notesStore.getNote('note1'); // Verify expect(notesStore.getNote).toHaveBeenCalledWith('note1'); expect(result).toEqual(mockNotes.note1); }); it('should return undefined when given an invalid ID', () => { // Setup vi.mocked(notesStore.getNote).mockReturnValue(undefined); // Execute const result = notesStore.getNote('invalid'); // Verify expect(notesStore.getNote).toHaveBeenCalledWith('invalid'); expect(result).toBeUndefined(); }); }); describe('getAllNotes', () => { it('should return all notes', () => { // Setup const notesList = Object.values(mockNotes); vi.mocked(notesStore.getAllNotes).mockReturnValue(notesList); // Execute const result = notesStore.getAllNotes(); // Verify expect(notesStore.getAllNotes).toHaveBeenCalled(); expect(result).toEqual(notesList); expect(result).toHaveLength(2); }); }); describe('createNote', () => { it('should create a new note', () => { // Setup const newNote = { id: 'note3', title: 'New Note', content: 'New content', createdAt: '2025-01-03T00:00:00.000Z' }; vi.mocked(notesStore.createNote).mockReturnValue(newNote); // Execute const result = notesStore.createNote('New Note', 'New content'); // Verify expect(notesStore.createNote).toHaveBeenCalledWith('New Note', 'New content'); expect(result).toEqual(newNote); }); }); describe('updateNote', () => { it('should update an existing note', () => { // Setup const updatedNote = { ...mockNotes.note1, title: 'Updated Title', content: 'Updated content' }; vi.mocked(notesStore.updateNote).mockReturnValue(updatedNote); // Execute const result = notesStore.updateNote('note1', { title: 'Updated Title', content: 'Updated content' }); // Verify expect(notesStore.updateNote).toHaveBeenCalledWith('note1', { title: 'Updated Title', content: 'Updated content' }); expect(result).toEqual(updatedNote); }); it('should return undefined when updating a non-existent note', () => { // Setup vi.mocked(notesStore.updateNote).mockReturnValue(undefined); // Execute const result = notesStore.updateNote('invalid', { title: 'Updated Title', content: 'Updated content' }); // Verify expect(notesStore.updateNote).toHaveBeenCalledWith('invalid', { title: 'Updated Title', content: 'Updated content' }); expect(result).toBeUndefined(); }); }); describe('deleteNote', () => { it('should delete an existing note', () => { // Setup vi.mocked(notesStore.deleteNote).mockReturnValue(true); // Execute const result = notesStore.deleteNote('note1'); // Verify expect(notesStore.deleteNote).toHaveBeenCalledWith('note1'); expect(result).toBe(true); }); it('should return false when deleting a non-existent note', () => { // Setup vi.mocked(notesStore.deleteNote).mockReturnValue(false); // Execute const result = notesStore.deleteNote('invalid'); // Verify expect(notesStore.deleteNote).toHaveBeenCalledWith('invalid'); expect(result).toBe(false); }); }); }); // Create a separate test file for the MCP server tools import { writeFileSync } from 'fs'; import { join } from 'path'; // Create a test file for the MCP server tools const serverToolsTestContent = `import { describe, it, expect, vi, beforeEach } from 'vitest'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; // Mock the notes store vi.mock('./notes-store.js', () => { const mockStore = { getNote: vi.fn(), getAllNotes: vi.fn(), createNote: vi.fn(), updateNote: vi.fn(), deleteNote: vi.fn() }; return { notesStore: mockStore }; }); // Import the mocked notesStore import { notesStore } from './notes-store.js'; describe('MCP Server Tools', () => { let server: McpServer; let toolCallback: Function; // Capture the tool callback for testing const mockTool = vi.fn().mockImplementation((name, schema, callback) => { if (name === 'getNote') { toolCallback = callback; } return { name, schema }; }); beforeEach(() => { // Reset mocks vi.resetAllMocks(); // Create a mock server server = { tool: mockTool } as unknown as McpServer; }); describe('getNote tool', () => { it('should return a note when given a valid ID', async () => { // Setup const mockNote = { id: 'note1', title: 'Sample Note 1', content: 'This is a sample note content.', createdAt: '2025-01-01T00:00:00.000Z' }; vi.mocked(notesStore.getNote).mockReturnValue(mockNote); // Register the tool to capture the callback server.tool('getNote', { noteId: 'string' }, async ({ noteId }) => { const note = notesStore.getNote(noteId); if (!note) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, error: 'Note not found', noteId }, null, 2) } ] }; } return { content: [ { type: 'text', text: JSON.stringify({ success: true, note }, null, 2) } ] }; }); // Execute the callback directly const result = await toolCallback({ noteId: 'note1' }); // Verify expect(notesStore.getNote).toHaveBeenCalledWith('note1'); expect(result.content[0].type).toBe('text'); const parsedResult = JSON.parse(result.content[0].text); expect(parsedResult.success).toBe(true); expect(parsedResult.note).toEqual(mockNote); }); }); }); `; // Write the server tools test file try { writeFileSync(join(process.cwd(), 'src/server-tools.test.ts'), serverToolsTestContent); console.log('Created server-tools.test.ts file'); } catch (error) { console.error('Failed to create server-tools.test.ts file:', error); }

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/jasonkneen/mcp-server-ts'

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