Skip to main content
Glama

Readwise MCP Server

by IAmAlexander
mock-client.ts6.3 kB
import { Book, Document, Highlight, PaginatedResponse, SearchParams, SearchResult } from '../types/index.js'; /** * Mock data for testing */ const MOCK_BOOKS: Book[] = [ { id: 'book-1', title: 'The Art of Computer Programming', author: 'Donald Knuth', category: 'books', source: 'kindle', cover_image_url: 'https://example.com/book1.jpg', updated: '2023-05-15T10:00:00Z' }, { id: 'book-2', title: 'Clean Code', author: 'Robert C. Martin', category: 'books', source: 'kindle', cover_image_url: 'https://example.com/book2.jpg', updated: '2023-06-20T14:30:00Z' }, { id: 'book-3', title: 'Artificial Intelligence: A Modern Approach', author: 'Stuart Russell, Peter Norvig', category: 'books', source: 'kindle', cover_image_url: 'https://example.com/book3.jpg', updated: '2023-07-10T09:15:00Z' } ]; const MOCK_HIGHLIGHTS: Highlight[] = [ { id: 'highlight-1', text: 'Programs should be written for people to read, and only incidentally for machines to execute.', note: 'Important principle of code readability', location: 42, color: 'yellow', book_id: 'book-1', updated: '2023-05-20T11:30:00Z', created_at: '2023-05-15T11:30:00Z', updated_at: '2023-05-20T11:30:00Z' }, { id: 'highlight-2', text: 'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.', note: '', location: 105, color: 'blue', book_id: 'book-2', updated: '2023-06-25T16:45:00Z', created_at: '2023-06-20T16:45:00Z', updated_at: '2023-06-25T16:45:00Z' }, { id: 'highlight-3', text: 'Machine learning is the science of getting computers to act without being explicitly programmed.', note: 'Definition of ML', location: 231, color: 'green', book_id: 'book-3', updated: '2023-07-12T10:20:00Z', created_at: '2023-07-10T10:20:00Z', updated_at: '2023-07-12T10:20:00Z' } ]; const MOCK_DOCUMENTS: Document[] = [ { id: 'doc-1', title: 'An Introduction to Neural Networks', author: 'John Smith', source: 'web', url: 'https://example.com/neural-networks', created_at: '2023-08-01T13:10:00Z', updated_at: '2023-08-05T13:10:00Z' }, { id: 'doc-2', title: 'The Future of AI', author: 'Jane Doe', source: 'web', url: 'https://example.com/future-ai', created_at: '2023-08-05T15:25:00Z', updated_at: '2023-08-10T15:25:00Z' } ]; /** * Mock implementation of the Readwise API for testing * This implements the same methods as ReadwiseAPI without formally implementing the interface */ export class MockReadwiseAPI { /** * Simulate network delay for realistic testing */ private async delay(ms: number = 100): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Get a list of books from the mock database */ async getBooks(params: any = {}): Promise<PaginatedResponse<Book>> { await this.delay(); const page = params.page || 1; const pageSize = params.page_size || 10; const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; return { count: MOCK_BOOKS.length, next: endIndex < MOCK_BOOKS.length ? `/api/books?page=${page + 1}` : null, previous: page > 1 ? `/api/books?page=${page - 1}` : null, results: MOCK_BOOKS.slice(startIndex, endIndex) }; } /** * Get a list of highlights from the mock database */ async getHighlights(params: any = {}): Promise<PaginatedResponse<Highlight>> { await this.delay(); let highlights = [...MOCK_HIGHLIGHTS]; // Filter by book_id if provided if (params.book_id) { highlights = highlights.filter(h => h.book_id === params.book_id); } const page = params.page || 1; const pageSize = params.page_size || 10; const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; return { count: highlights.length, next: endIndex < highlights.length ? `/api/highlights?page=${page + 1}` : null, previous: page > 1 ? `/api/highlights?page=${page - 1}` : null, results: highlights.slice(startIndex, endIndex) }; } /** * Get a list of documents from the mock database */ async getDocuments(params: any = {}): Promise<PaginatedResponse<Document>> { await this.delay(); const page = params.page || 1; const pageSize = params.page_size || 10; const startIndex = (page - 1) * pageSize; const endIndex = startIndex + pageSize; return { count: MOCK_DOCUMENTS.length, next: endIndex < MOCK_DOCUMENTS.length ? `/api/documents?page=${page + 1}` : null, previous: page > 1 ? `/api/documents?page=${page - 1}` : null, results: MOCK_DOCUMENTS.slice(startIndex, endIndex) }; } /** * Search highlights from the mock database */ async searchHighlights(params: SearchParams): Promise<SearchResult[]> { await this.delay(); // Simple case-insensitive search implementation const query = params.query.toLowerCase(); const results = MOCK_HIGHLIGHTS.filter(h => h.text.toLowerCase().includes(query) || (h.note && h.note.toLowerCase().includes(query)) ).map(highlight => { const book = MOCK_BOOKS.find(b => b.id === highlight.book_id)!; return { highlight, book, score: 0.9 // High relevance score for all results in mock data }; }); // Apply limit if specified const limit = params.limit || 10; return results.slice(0, limit); } /** * Get a book by ID */ async getBook(bookId: string): Promise<Book | null> { await this.delay(); return MOCK_BOOKS.find(book => book.id === bookId) || null; } /** * Get a highlight by ID */ async getHighlight(highlightId: string): Promise<Highlight | null> { await this.delay(); return MOCK_HIGHLIGHTS.find(highlight => highlight.id === highlightId) || null; } /** * Get a document by ID */ async getDocument(documentId: string): Promise<Document | null> { await this.delay(); return MOCK_DOCUMENTS.find(document => document.id === documentId) || null; } }

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/IAmAlexander/readwise-mcp'

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