A simple REST API that returns random quotes from Goodreads with built-in caching, rate limiting, and comprehensive monitoring.
# Install dependencies
npm install
# Start REST API server (listens on localhost:8000)
npm start
# Start MCP server (for Claude Desktop / Claude Code)
npm run mcp
# Run tests
npm testFull API documentation is available at: /api/docs
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/quotes |
Get up to 30 random quotes (supports ?count=N parameter) |
| GET | /api/v1/quotes/random |
Get a single random quote |
| GET | /api/v1/cache/stats |
View cache hit/miss statistics |
| GET | /health |
Health check for monitoring |
# Get 5 random quotes
curl http://localhost:8000/api/v1/quotes?count=5
# Get a single quote
curl http://localhost:8000/api/v1/quotes/random
# Check API health
curl http://localhost:8000/health- Random Quotes: Scrapes and caches quotes from Goodreads (30 quotes per page, 100 pages)
- Smart Caching: In-memory cache with TTL, fallback to cached data on errors
- Rate Limiting: 100 requests per minute to
/api/* - Request Logging: Structured JSON logs with unique request IDs for tracing
- Retry Backoff: Exponential backoff (1s, 2s, 4s...) when Goodreads is unavailable
- Graceful Shutdown: Clean shutdown on SIGTERM/SIGINT signals
- Health Checks:
/healthendpoint for load balancers and k8s probes - CORS: Configurable cross-origin requests
- MCP Integration: Standalone MCP server for AI assistants (Claude Desktop, Claude Code)
All settings are environment variables (see .env.example):
| Variable | Default | Description |
|---|---|---|
PORT |
8000 | Server port |
CACHE_TTL_MINUTES |
60 | Cache expiration time |
SCRAPER_TIMEOUT_MS |
15000 | HTTP request timeout |
SCRAPER_RETRIES |
2 | Number of retry attempts |
SCRAPER_RETRY_DELAY_MS |
1000 | Base delay for exponential backoff |
RATE_LIMIT_MAX |
100 | Max requests per window |
RATE_LIMIT_WINDOW_MS |
60000 | Rate limit window |
This project includes a standalone MCP (Model Context Protocol) server that exposes quote functionality to AI assistants.
npm run mcpThe server will start on stdio and listen for JSON-RPC requests. Available tools:
- get_random_quote: Get a single random quote
- get_quotes: Get multiple quotes (supports optional
countparameter, 1-30) - get_cache_stats: Get cache statistics (hits, misses, expirations, hit rate)
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"random-quote-api": {
"command": "node",
"args": ["/path/to/random-quote-api/src/mcp.js"]
}
}
}docker build -t random-quote-api .
docker run -p 8000:8000 random-quote-apisrc/
app.js # Express app setup
server.js # REST API entry point with graceful shutdown
mcp.js # MCP server (JSON-RPC over stdio)
middleware/requestLogger.js # Request ID and access logging
services/quotesService.js # Business logic
cache/quotesCache.js # In-memory cache with TTL
scraper/goodreadsScraper.js # Goodreads HTML scraping
utils/
logger.js # Structured JSON logging
fetchWithRetry.js # HTTP fetch with exponential backoff
npm test # Run all tests
npm test:watch # Watch mode
npm test:coverage # Coverage reportTests use mocked scraper data (no network calls), making them fast and reliable.
- Response Time: ~50-100ms (cached) or ~500-1000ms (first request)
- Cache Hit Rate: ~80%+ in typical usage
- Startup Time: <100ms
- Memory: ~10-20MB with full cache
MIT