rhofkens/mcp-quotes-server
If you are the rightful owner of mcp-quotes-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
An MCP that serves quotes from famous or less famous people.
MCP Quotes Server
A Model Context Protocol (MCP) server that provides quotes based on user requests. This server demonstrates the basic implementation of an MCP server using TypeScript and the official MCP SDK.
Features
- MCP Protocol Compliance: Implements the Model Context Protocol for seamless integration with MCP clients
- Dual Transport Support: Supports both stdio and HTTP/HTTPS transports for flexible deployment
- Real Quote Retrieval: Integrates with Serper.dev API to retrieve real quotes from specified persons or topics
- Multiple Quote Support: Request 1-10 quotes at once with automatic formatting
- Prompt Template Resources: Provides MCP resources with structured prompt templates for quote requests
- Parameter Validation: Comprehensive input validation with detailed error messages
- Robust Error Handling: Comprehensive error handling with retry logic and exponential backoff
- Structured Logging: File-based logging with Winston for monitoring and debugging
- Security Features: DNS rebinding protection, CORS configuration, and HTTPS support
- Session Management: HTTP session tracking with automatic cleanup and statistics
- TypeScript: Built with TypeScript for type safety and modern development practices
- Flexible Transport: Uses standard input/output or HTTP/HTTPS for communication with MCP clients
Prerequisites
- Node.js (version 18 or higher)
- npm (Node Package Manager)
- Serper.dev API key (required for quote retrieval functionality)
Installation
- Clone this repository:
git clone <repository-url>
cd mcp-quotes-server
- Install dependencies:
npm install
- Configure your Serper.dev API key:
Set the SERPER_API_KEY
environment variable with your API key from serper.dev:
export SERPER_API_KEY="your-serper-api-key-here"
You can also create a .env
file in the project root:
echo "SERPER_API_KEY=your-serper-api-key-here" > .env
HTTP Transport Configuration
This server supports both stdio and HTTP transports. By default, it uses stdio transport for backwards compatibility. To enable HTTP transport, configure the following environment variables:
Environment Variables
Variable | Description | Default | Required |
---|---|---|---|
MCP_HTTP_ENABLED | Enable HTTP transport | false | No |
MCP_HTTP_PORT | HTTP server port | 3000 | No |
MCP_HTTP_HOST | HTTP server host | localhost | No |
MCP_HTTP_ALLOWED_ORIGINS | Comma-separated CORS origins | http://localhost:3000 | No |
MCP_HTTP_ALLOWED_HOSTS | Comma-separated allowed hosts for DNS rebinding protection | localhost | No |
MCP_HTTPS_ENABLED | Enable HTTPS (requires certificates) | false | No |
MCP_HTTPS_CERT_PATH | Path to SSL certificate file | - | If HTTPS enabled |
MCP_HTTPS_KEY_PATH | Path to SSL private key file | - | If HTTPS enabled |
Basic HTTP Configuration
To run the server with HTTP transport:
# Enable HTTP transport on default port 3000
export MCP_HTTP_ENABLED=true
npm start
Or with custom configuration:
# Custom HTTP configuration
export MCP_HTTP_ENABLED=true
export MCP_HTTP_PORT=8080
export MCP_HTTP_HOST=0.0.0.0
export MCP_HTTP_ALLOWED_ORIGINS="https://example.com,https://app.example.com"
export MCP_HTTP_ALLOWED_HOSTS="localhost,127.0.0.1,example.com"
npm start
HTTPS Configuration
For production deployments with HTTPS:
# HTTPS configuration
export MCP_HTTP_ENABLED=true
export MCP_HTTPS_ENABLED=true
export MCP_HTTPS_CERT_PATH="/path/to/certificate.pem"
export MCP_HTTPS_KEY_PATH="/path/to/private-key.pem"
export MCP_HTTP_ALLOWED_ORIGINS="https://yourapp.com"
export MCP_HTTP_ALLOWED_HOSTS="yourapp.com"
npm start
Security Features
DNS Rebinding Protection
The server automatically validates the Host
header against allowed hosts to prevent DNS rebinding attacks.
CORS Configuration
Cross-Origin Resource Sharing (CORS) is configured to only allow requests from specified origins.
Session Management
HTTP transport uses session-based communication with automatic cleanup of inactive sessions.
HTTP Endpoints
When HTTP transport is enabled, the server exposes the following endpoints:
POST /mcp
- Main MCP communication endpointGET /mcp
- Server-to-client notifications via Server-Sent EventsDELETE /mcp
- Session terminationGET /health
- Health check endpointGET /sessions
- Session statistics (for monitoring)
Development Setup
Building the Project
To compile the TypeScript code to JavaScript:
npm run build
This will create a dist
directory with the compiled JavaScript files.
Running the Server
To start the MCP server, you have several options:
Option 1 - Using npm start (Recommended for development):
npm start
Option 2 - Using compiled JavaScript (Recommended for MCP inspector):
npm run build
node dist/start.js
Option 3 - Using ts-node directly:
npx ts-node src/start.ts
The server will start and listen for MCP connections via stdio transport.
For MCP Inspector Testing:
Use any of the above commands in your MCP client configuration. The most reliable option for MCP inspector is node dist/start.js
after building the project.
Running Tests
To run the test suite:
npm test
To run tests with coverage:
npm test -- --coverage
Code Quality
To run linting checks:
npm run lint
To format code:
npm run format
Usage
Usage
Available Tools
get_quote
Retrieves real quotes from a specified person or topic using the Serper.dev API. Enhanced with support for requesting multiple quotes at once.
Parameters:
person
(required): The name of the person to get a quote fromtopic
(optional): The topic or subject for the quotenumberOfQuotes
(optional): Number of quotes to retrieve (1-10, defaults to 1)
Example Usage with MCP Client:
// Example 1: Single quote request
const result = await client.callTool({
name: "get_quote",
arguments: {
person: "Albert Einstein",
topic: "science",
},
});
// Expected response (real quote from Serper.dev):
{
content: [
{
type: "text",
text: "Science without religion is lame, religion without science is blind.",
},
];
}
// Example 2: Multiple quotes request
const multipleQuotes = await client.callTool({
name: "get_quote",
arguments: {
person: "Maya Angelou",
numberOfQuotes: 3,
},
});
// Expected response (formatted multiple quotes):
{
content: [
{
type: "text",
text: `1. "If you don't like something, change it. If you can't change it, change your attitude."
2. "There is no greater agony than bearing an untold story inside you."
3. "Try to be a rainbow in someone's cloud."`,
},
];
}
Parameter Validation:
The tool includes comprehensive parameter validation:
- Person validation: Ensures person name is provided and not empty
- Topic validation: Optional string parameter
- NumberOfQuotes validation: Must be between 1 and 10 if provided
- Detailed error messages: Clear feedback for invalid parameters
Error Handling:
The tool provides comprehensive error handling:
- Configuration errors: Missing or invalid API key
- API errors: Rate limiting, authentication failures, network issues
- Validation errors: Invalid parameter values with detailed messages
- Fallback messages: When no suitable quotes are found
Logging:
All API requests and responses are logged to files for monitoring:
combined.log
: All log entrieserrors.log
: Error-level messages only
Available Resources
prompt-template://quote-request
Provides a structured prompt template for quote requests that follows MCP resource standards.
Usage with MCP Client:
// List available resources
const resources = await client.listResources();
// Access the prompt template resource
const template = await client.readResource({
uri: "prompt-template://quote-request",
});
// The resource contains structured information about:
// - Parameter specifications (person, topic, numberOfQuotes)
// - Usage examples and best practices
// - Input validation requirements
Resource Content Structure:
{
"name": "Prompt Template for Quote Requests",
"description": "A structured template for requesting quotes from famous people with specific topics and quantities.",
"parameters": [
{
"name": "person",
"type": "string",
"required": true,
"description": "The name of the person to get quotes from"
},
{
"name": "topic",
"type": "string",
"required": false,
"description": "Optional topic to filter quotes by"
},
{
"name": "numberOfQuotes",
"type": "number",
"required": false,
"description": "Number of quotes to retrieve (1 to 10)"
}
],
"examples": [
{
"title": "Single Quote Request",
"parameters": {
"person": "Albert Einstein",
"topic": "imagination"
}
},
{
"title": "Multiple Quotes Request",
"parameters": {
"person": "Maya Angelou",
"numberOfQuotes": 5
}
}
]
}
MCP Client Integration
Stdio Transport (Default)
To use this server with an MCP client via stdio transport:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
// Create transport that runs this server
const transport = new StdioClientTransport({
command: "npm",
args: ["start"],
cwd: "/path/to/mcp-quotes-server",
});
// Create and connect client
const client = new Client({
name: "example-client",
version: "1.0.0",
});
await client.connect(transport);
// List available tools
const tools = await client.listTools();
console.log("Available tools:", tools);
// Call the get_quote tool
const result = await client.callTool({
name: "get_quote",
arguments: {
person: "Shakespeare",
topic: "love",
},
});
console.log("Quote result:", result);
HTTP Transport
To use this server with HTTP transport:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
// Create HTTP transport
const transport = new StreamableHTTPClientTransport({
baseUrl: "http://localhost:3000",
});
// Create and connect client
const client = new Client({
name: "example-http-client",
version: "1.0.0",
});
await client.connect(transport);
// Use the same API as stdio transport
const tools = await client.listTools();
const result = await client.callTool({
name: "get_quote",
arguments: {
person: "Einstein",
topic: "imagination",
},
});
HTTPS Transport
For secure HTTPS connections:
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
// Create HTTPS transport
const transport = new StreamableHTTPClientTransport({
baseUrl: "https://your-mcp-server.com",
headers: {
Authorization: "Bearer your-auth-token",
},
});
const client = new Client({
name: "secure-client",
version: "1.0.0",
});
await client.connect(transport);
MCP Inspector Tool Usage
Quick Setup (Recommended)
The easiest way to test this MCP server is using the published NPM package:
- Install the MCP Inspector globally:
npm install -g @modelcontextprotocol/inspector
- Start the MCP Inspector:
mcp-inspector
- In the MCP Inspector interface:
- Transport Type: STDIO
- Command:
npx
- Arguments:
@rhofkens/mcp-quotes-server@0.1.3
- Click "Connect"
Alternative: Local Development Setup
If you want to test with local code changes:
- Install the MCP Inspector globally:
npm install -g @modelcontextprotocol/inspector
- Build the project:
npm run build
- Start the MCP Inspector:
mcp-inspector
- In the MCP Inspector interface:
- Set the command to:
node
- Set the arguments to:
dist/start.js
- Set the working directory to your project path
- Click "Connect"
- Set the command to:
Testing with MCP Inspector
Once connected, you can:
- List Tools: View available tools including
get_quote
- Test get_quote Tool:
- Select the
get_quote
tool - Provide parameters like
{"person": "Einstein", "topic": "science"}
- Execute and view results
- Select the
- List Resources: View available resources including
prompt-template://quote-request
- Test Resources: Access and view the prompt template resource content
Common MCP Inspector Issues
- Connection Issues: Ensure the server builds successfully with
npm run build
- Tool Errors: Check that
SERPER_API_KEY
environment variable is set - Resource Errors: Verify the resource URI format is correct
Claude Desktop Integration
Configuration
To use this MCP server with Claude Desktop, you need to configure it in your Claude Desktop settings:
-
Open Claude Desktop Configuration:
- On macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- On Windows:
%APPDATA%/Claude/claude_desktop_config.json
- On Linux:
~/.config/Claude/claude_desktop_config.json
- On macOS:
-
Add Server Configuration:
{
"mcpServers": {
"quotes-server": {
"command": "node",
"args": ["dist/start.js"],
"cwd": "/path/to/your/mcp-quotes-server",
"env": {
"SERPER_API_KEY": "your-serper-api-key-here"
}
}
}
}
Alternative Configuration with npm
If you prefer to use npm:
{
"mcpServers": {
"quotes-server": {
"command": "npm",
"args": ["start"],
"cwd": "/path/to/your/mcp-quotes-server",
"env": {
"SERPER_API_KEY": "your-serper-api-key-here"
}
}
}
}
Using the Server in Claude Desktop
After configuration and restarting Claude Desktop:
-
Verify Connection: Look for the MCP server icon in Claude Desktop
-
Use the get_quote Tool: Type messages like:
- "Get me a quote from Einstein about science"
- "Find 3 quotes from Maya Angelou"
- "Get quotes about leadership from Winston Churchill"
-
Access Resources: The prompt template resource will be available for structured requests
Troubleshooting Claude Desktop Integration
- Server Not Appearing: Check the configuration file syntax and restart Claude Desktop
- Tool Not Working: Verify the SERPER_API_KEY is correctly set in the environment
- Path Issues: Use absolute paths in the configuration
Troubleshooting
Common Issues and Solutions
1. API Key Problems
Issue: Error: Missing or invalid Serper API key
Solutions:
- Verify your API key is valid at serper.dev
- Check the environment variable is set:
echo $SERPER_API_KEY
- For
.env
file, ensure no spaces around the=
sign - Restart your terminal/IDE after setting environment variables
2. Build and Installation Issues
Issue: npm install
fails or TypeScript compilation errors
Solutions:
- Ensure Node.js version 18+ is installed:
node --version
- Clear npm cache:
npm cache clean --force
- Delete
node_modules
and reinstall:rm -rf node_modules && npm install
- Check for TypeScript version compatibility:
npm list typescript
3. MCP Connection Issues
Issue: MCP clients cannot connect to the server
Solutions:
- Verify the server builds successfully:
npm run build
- Test the server directly:
node dist/start.js
- Check for port conflicts if using HTTP transport
- Ensure proper permissions for the executable
4. Quote Retrieval Issues
Issue: No quotes returned or API errors
Solutions:
- Verify API key is correctly configured
- Check network connectivity
- Try different person names or topics
- Review logs in
combined.log
for detailed error information - Ensure the person name is spelled correctly and is well-known
5. HTTP Transport Issues
Issue: HTTP server not starting or connection refused
Solutions:
- Check port availability:
lsof -i :3000
(replace 3000 with your port) - Verify environment variables are set correctly
- Check firewall settings
- Ensure CORS origins are properly configured
- For HTTPS, verify certificate paths are correct
6. Testing and Coverage Issues
Issue: Tests failing or coverage not meeting requirements
Solutions:
- Run tests individually to identify specific failures:
npm test -- --testNamePattern="specific test"
- Check test environment variables are set
- Verify mock data is properly configured
- Review test logs for specific error messages
7. Logging Issues
Issue: Log files not created or logs not appearing
Solutions:
- Check write permissions in the project directory
- Verify Winston configuration in
src/utils/logger.ts
- Ensure the log directory exists and is writable
- Check for disk space issues
Getting Help
If you continue to experience issues:
- Check the logs: Review
combined.log
anderrors.log
for detailed error information - Review the documentation: Ensure you're following the setup steps correctly
- Check GitHub Issues: Look for similar issues in the project repository
- Create a detailed issue report: Include error messages, logs, and system information
Project Structure
mcp-quotes-server/
āāā src/
ā āāā index.ts # Main server entry point
ā āāā start.ts # Server startup script
ā āāā services/
ā ā āāā serper-service.ts # Serper.dev API integration
ā ā āāā http-transport-service.ts # HTTP transport service
ā āāā types/
ā ā āāā serper-types.ts # Serper API TypeScript interfaces
ā ā āāā serper-errors.ts # Custom error classes
ā ā āāā resource-types.ts # MCP resource TypeScript interfaces
ā ā āāā validation-types.ts # Parameter validation types
ā ā āāā http-transport-types.ts # HTTP transport TypeScript interfaces
ā āāā config/
ā ā āāā environment-config.ts # Environment configuration parsing
ā āāā resources/
ā ā āāā prompt-template-content.ts # Prompt template resource content
ā āāā utils/
ā āāā logger.ts # Winston logging configuration
ā āāā parameter-validator.ts # Input parameter validation
āāā __tests__/
ā āāā serper-service.test.ts # SerperService unit tests
ā āāā mcp-tool-integration.test.ts # MCP tool integration tests
ā āāā index.test.ts # Main server functionality tests
ā āāā parameter-validator.test.ts # Parameter validation tests
ā āāā prompt-template-resource.test.ts # Resource content tests
ā āāā get-quote-enhanced.test.ts # Enhanced tool integration tests
āāā dist/ # Compiled JavaScript (after build)
āāā coverage/ # Test coverage reports
āāā docs/ # Project documentation
ā āāā decisions/ # Architecture Decision Records
ā āāā guidelines/ # Development guidelines
ā āāā plans/ # Implementation plans
ā āāā tasks/ # Detailed task specifications
āāā combined.log # Winston log file (all entries)
āāā errors.log # Winston log file (errors only)
āāā package.json # Dependencies and scripts
āāā tsconfig.json # TypeScript configuration
āāā jest.config.js # Jest test configuration
āāā .eslintrc.js # ESLint configuration
āāā .prettierrc # Prettier configuration
āāā README.md # This file
Development
Architecture
This MCP server follows a monolithic TypeScript architecture as outlined in the project guidelines. The server:
- Creates an
McpServer
instance with name and version - Registers tools using
server.registerTool()
- Uses
StdioServerTransport
for communication - Provides type-safe tool definitions with Zod schemas
Adding New Tools
To add a new tool:
- Register the tool using
server.registerTool()
- Define the input schema using Zod
- Implement the async handler function
- Add corresponding tests
Example:
server.registerTool(
"new_tool",
{
title: "New Tool",
description: "Description of the new tool",
inputSchema: {
param1: z.string(),
param2: z.number().optional(),
},
},
async ({ param1, param2 }) => {
// Tool implementation
return {
content: [
{
type: "text",
text: `Result: ${param1}`,
},
],
};
}
);
Working with Resources
To access MCP resources in your applications:
// List all available resources
const resources = await client.listResources();
console.log("Available resources:", resources);
// Read the prompt template resource
const promptTemplate = await client.readResource({
uri: "prompt-template://quote-request",
});
// Parse the JSON content
const templateData = JSON.parse(promptTemplate.contents[0].text);
console.log("Template parameters:", templateData.parameters);
Current Status
This is Step 04 of the MCP Quotes Server implementation. The current version provides:
- ā Basic MCP server setup with stdio transport
- ā Dual transport support (stdio and HTTP/HTTPS)
- ā
get_quote
tool registration and discovery - ā Serper.dev API integration for real quote retrieval
- ā Enhanced get_quote tool with numberOfQuotes parameter (1-10 quotes)
- ā Prompt template resources following MCP standards
- ā Comprehensive parameter validation with detailed error messages
- ā Comprehensive error handling and retry logic
- ā File-based logging with Winston
- ā HTTP transport with session management
- ā Security features (DNS rebinding protection, CORS, HTTPS)
- ā Environment-based configuration
- ā Comprehensive unit and integration tests (>70% coverage)
- ā TypeScript configuration and build system
- ā Testing infrastructure with Jest
- ā Code quality tools (ESLint, Prettier)
Roadmap
Future steps will include:
- Additional quote sources and providers
- Enhanced quote filtering and categorization
- Advanced resource templates
- Deployment automation and containerization
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and linting
- Submit a pull request
License
MIT License - see LICENSE file for details.