This MCP server implementation is sponsored by systemprompt.io β creators of the world's first native mobile MCP client for iOS and Android β and provided completely free and open source to the community.
If you find this project useful, we'd appreciate:
- β A star on this repository
- π A like/follow on our social channels
- π Sharing with your network
Your support helps us continue creating valuable open source tools for the AI community!
π Learn More: For an interactive walkthrough of this implementation with live SDK testing, visit systemprompt.io/mcp-server
A production-ready Model Context Protocol (MCP) server that demonstrates the complete MCP specification including OAuth 2.1, sampling, elicitation, structured data validation, and real-time notifications.
This implementation uses Reddit as a real-world example to demonstrate OAuth 2.1 flow and advanced MCP features, but the architecture is designed to be easily adapted for any API that requires OAuth authentication.
This server works with any MCP-compliant client that supports advanced features like sampling and notifications.
This server is fully compatible with the MCP Inspector, providing perfect support for:
- β OAuth 2.1 Authentication - Complete flow with PKCE
- β Tools - All Reddit interaction capabilities
- β Prompts - Dynamic content generation prompts
- β Sampling - AI-assisted content with human approval
- β Notifications - Real-time progress updates
Test it yourself: npm run inspector
This implementation uses Reddit's API as a real-world example to demonstrate how to build a complete OAuth 2.1 flow in an MCP server. Reddit was chosen because:
- It requires OAuth authentication for most operations
- It provides a rich API for demonstrating various MCP features
- It's a well-documented, publicly accessible API
- It showcases real-world authentication challenges and solutions
Note: While this server uses Reddit, the OAuth implementation and architecture patterns are designed to be easily adapted for any OAuth-based API (GitHub, Google, Slack, etc.).
This repository serves as the gold standard for MCP server implementations, showcasing:
- Complete MCP Spec Coverage: Every feature from OAuth to sampling is implemented
- Production Architecture: Multi-user sessions, security, and scalability built-in
- Developer Experience: Clean code structure perfect for learning or forking
- Real-World OAuth Integration: Full OAuth 2.1 flow with PKCE, JWT tokens, and session management
- AI-Native Design: Deep integration with LLMs for content generation and analysis
- Features
- Quick Start
- Architecture
- OAuth Implementation
- Tool Reference
- Advanced Features
- Using as a Template
- Development
- Code Structure
- Contributing
- Related Projects
- π OAuth 2.1 Flow: Complete 8-step implementation with PKCE and JWT
- π οΈ Tool System: Comprehensive tools for Reddit interaction
- π Resources & Prompts: Dynamic prompt generation and resource management
- π€ Sampling: AI-assisted content generation with human oversight
- π¬ Elicitation: Dynamic user input gathering during tool execution
- β Structured Data: JSON Schema validation for all inputs/outputs
- π‘ Notifications: Real-time progress updates and status notifications
- π Session Management: Multi-user support with automatic cleanup
- Content Discovery: Search and analyze Reddit content
- User Interactions: View messages, notifications, and manage account
- Subreddit Information: Retrieve subreddit details and posts
- Comment Threads: Navigate and analyze Reddit discussions
- TypeScript: Full type safety with comprehensive interfaces
- Modular Architecture: Clean separation of concerns
- Error Handling: Robust error management with custom error types
- Docker Support: Ready for containerized deployment
- Testing: Example test implementations included
- Documentation: Extensive inline documentation and examples
Run the server instantly with Docker - no installation required:
-
Create a Reddit app at reddit.com/prefs/apps
- Choose "script" type
- Set redirect URI:
http://localhost:3000/oauth/reddit/callback
-
Create initial
.env
file:
cat > .env << EOF
REDDIT_CLIENT_ID=your_reddit_client_id
REDDIT_CLIENT_SECRET=your_reddit_client_secret
JWT_SECRET=any_random_string_here
EOF
# Run with Docker (pulls image automatically)
docker run -it --rm \
-p 3000:3000 \
--env-file .env \
--name mcp-reddit \
node:20-slim \
npx @systemprompt/systemprompt-mcp-server
- In your MCP client, connect to
http://localhost:3000
- The OAuth flow will start automatically
- Authorize the app in your browser
- Copy the returned OAuth token
# Stop the container (Ctrl+C)
# Add the OAuth token to your .env file
echo "OAUTH_ACCESS_TOKEN=your_oauth_token_here" >> .env
# Restart with the token
docker run -it --rm \
-p 3000:3000 \
--env-file .env \
node:20-slim \
npx @systemprompt/systemprompt-mcp-server
Now you can use all Reddit tools with your authenticated session!
# Via npm
npm install -g @systemprompt/systemprompt-mcp-server
# Via npx (no installation)
npx @systemprompt/systemprompt-mcp-server
# Clone for development
git clone https://github.com/systempromptio/systemprompt-mcp-server.git
cd systemprompt-mcp-server
npm install
npm run build
-
Create Reddit App: reddit.com/prefs/apps
- Choose "script" type
- Set redirect URI:
http://localhost:3000/oauth/reddit/callback
-
Set Environment Variables:
Create a .env
file in the project root:
# Required for Reddit API
REDDIT_CLIENT_ID=your_reddit_client_id
REDDIT_CLIENT_SECRET=your_reddit_client_secret
JWT_SECRET=your_jwt_secret # Secret for JWT signing
# Optional
PORT=3000 # Server port (default: 3000)
OAUTH_ISSUER=http://localhost:3000 # OAuth issuer URL
REDIRECT_URL=http://localhost:3000/oauth/reddit/callback # OAuth redirect
REDDIT_USER_AGENT=linux:systemprompt-mcp-reddit:v2.0.0 # Reddit user agent
REDDIT_USERNAME=your_reddit_username # Your Reddit username (optional)
LOG_LEVEL=debug # Logging level (debug, info, warn, error)
Note: Environment variables are required for both local development and Docker deployment.
# Build the TypeScript code
npm run build
# Run the built server
node build/index.js
# Development with watch mode
npm run watch
# In another terminal:
node build/index.js
# With Docker
npm run docker
This implementation follows clean architecture principles with clear separation between layers:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Client Application β
β (systemprompt.io) β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β MCP Protocol
ββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββ
β MCP Server Layer β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββββ β
β β OAuth 2.1 β β Session β β Notification β β
β β Handler β β Manager β β Manager β β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββββ β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββ
β Handler Layer β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββββ β
β β Tools β β Resources β β Sampling β β
β β Handler β β Handler β β Handler β β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββββ β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββ
β Service Layer β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββββ β
β β Reddit β β Auth β β Fetch β β
β β Service β β Service β β Service β β
β βββββββββββββββ βββββββββββββββ ββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
src/server.ts
: Main HTTP server setup and Express configurationsrc/server/
: Core server infrastructure (MCP, OAuth, auth management)src/handlers/
: Request handlers for tools, prompts, resources, and samplingsrc/services/
: Business logic and Reddit API integrationsrc/constants/
: Tool definitions, server configuration, and schemassrc/types/
: TypeScript type definitions and interfaces
This server implements the complete MCP OAuth 2.1 specification:
-
Initial 401 Response (src/server/oauth.ts)
WWW-Authenticate: Bearer realm="MCP Reddit Server"
-
Resource Metadata (src/server/oauth.ts)
{ "authorization_server": "http://localhost:3000/.well-known/oauth" }
-
Authorization Server Metadata (src/server/oauth.ts)
- Token endpoint configuration
- PKCE support declaration
- Grant types supported
-
Authorization Request (src/server/oauth.ts)
- PKCE code challenge
- State parameter for CSRF protection
- Reddit OAuth redirect handling
-
Reddit OAuth Callback (src/server/oauth.ts)
- Reddit authorization handling
- Secure state validation
-
Token Exchange (src/server/oauth.ts)
- PKCE verification
- JWT token generation
- Reddit credentials embedding
-
Authenticated Requests (src/server/middleware.ts)
- JWT validation
- Session management
- Request context injection
- PKCE Implementation: Prevents authorization code interception
- JWT Tokens: Secure credential storage and transmission
- Session Isolation: Each user has isolated Reddit credentials
- Automatic Cleanup: Sessions expire after inactivity
Search across Reddit with filters (src/handlers/tools/search-reddit.ts)
{
"query": "typescript MCP",
"subreddit": "programming", // Optional specific subreddit
"sort": "relevance",
"time": "week",
"limit": 10
}
Fetch a specific post with comments (src/handlers/tools/get-post.ts)
{
"id": "post_id_here" // Reddit post ID
}
Get subreddit posts (src/handlers/tools/get-channel.ts)
{
"subreddit": "programming",
"sort": "hot" // "hot", "new", or "controversial"
}
Fetch user notifications and messages (src/handlers/tools/get-notifications.ts)
{
"filter": "unread", // "all", "unread", "messages", "comments", "mentions"
"limit": 25,
"markRead": false
}
Retrieve a specific comment (src/handlers/tools/get-comment.ts)
{
"id": "comment_id_here",
"includeThread": true // Include full comment thread
}
Demonstrates user input gathering (src/handlers/tools/elicitation-example.ts)
{
"type": "input", // "input", "confirm", "choice"
"prompt": "Enter your choice",
"options": ["option1", "option2"] // For choice type
}
Demonstrates AI-assisted content generation (src/handlers/tools/sampling-example.ts)
{
"prompt": "Generate a code example",
"maxTokens": 1000,
"temperature": 0.7
}
Demonstrates structured data handling (src/handlers/tools/structured-data-example.ts)
{
"format": "json", // "json", "table", "markdown"
"data": { "key": "value" }
}
Demonstrates input validation (src/handlers/tools/validation-example.ts)
{
"test_string": "example",
"test_number": 42,
"test_enum": "option1"
}
Request server to log messages (src/handlers/tools/logging.ts)
{
"level": "info", // "debug", "info", "warning", "error"
"message": "Debug message",
"data": { "additional": "context" }
}
The sampling implementation (src/handlers/sampling.ts) follows the complete MCP specification:
// 1. Client requests AI assistance
await client.callTool("sampling_example", {
prompt: "Analyze this subreddit and suggest actions",
maxTokens: 1000,
temperature: 0.7
});
// 2. Server initiates sampling for content generation
const samplingRequest = {
method: "sampling/createMessage",
params: {
messages: [{
role: "user",
content: {
type: "text",
text: "Analyze this subreddit and suggest actions"
}
}],
maxTokens: 1000,
temperature: 0.7,
_meta: {
callback: "suggest_action"
}
}
};
// 3. AI generates content
// 4. Callback processes the response
// 5. Client receives the final result
Example implementation (src/handlers/tools/elicitation-example.ts):
// Call the elicitation example tool
await client.callTool("elicitation_example", {
type: "input",
prompt: "Enter post title",
options: []
});
// The tool demonstrates different elicitation types:
// - "input": Text input from user
// - "confirm": Yes/no confirmation
// - "choice": Multiple choice selection
Real-time updates during operations (src/handlers/notifications.ts):
// Send notifications during long-running operations
await sendProgressNotification("Processing request...", sessionId);
await sendSamplingCompleteNotification("Analysis complete", sessionId);
// Notifications are automatically sent to the MCP client
// providing real-time feedback during tool execution
All inputs use Zod schema validation (src/handlers/tool-handlers.ts):
// Example Zod schema for Reddit search
const SearchRedditSchema = z.object({
query: z.string().min(1).max(500).describe("Search query"),
subreddit: z.string().optional().describe("Optional subreddit filter"),
sort: z.enum(["relevance", "hot", "new", "top"]).default("relevance"),
time: z.enum(["hour", "day", "week", "month", "year", "all"]).default("all"),
limit: z.number().int().min(1).max(100).default(25)
});
// Validation is automatic and provides detailed error messages
const args = SearchRedditSchema.parse(request.params.arguments);
This codebase is designed to be forked and adapted for other MCP implementations:
git clone https://github.com/your-username/your-mcp-server.git
cd your-mcp-server
Replace Reddit-specific services in src/services/
with your API:
// src/services/your-api/your-service.ts
export class YourAPIService {
async fetchData(params: YourParams): Promise<YourData> {
// Your API integration
}
}
Create tools in src/handlers/tools/
:
// src/handlers/tools/your-tool.ts
export const yourTool: ToolDefinition = {
schema: {
name: "your_tool",
description: "What your tool does",
inputSchema: {
type: "object",
properties: {
// Your parameters
}
}
},
handler: async (params, context) => {
// Tool implementation
}
};
Modify src/constants/server/server-config.ts
:
export const serverConfig = {
name: "your-mcp-server",
version: "1.0.0",
description: "Your MCP server description"
};
export const serverCapabilities = {
tools: {},
prompts: {},
resources: {},
sampling: {}
};
- Node.js 18+
- npm or yarn
- Reddit account and app credentials
# Install dependencies
npm install
# Build TypeScript
npm run build
# Watch mode for development
npm run watch
# Run tests (requires OAuth tokens - see below)
npm run test
# Run end-to-end tests
npm run e2e
# Build and run with Docker
npm run docker
The server is fully compatible with the MCP Inspector, which provides a powerful interface for testing all MCP features:
# Build the server first
npm run build
# Launch the inspector with the built server
npx @modelcontextprotocol/inspector build/index.js
This command will:
- Build the TypeScript project
- Open the MCP Inspector documentation in your browser
- Launch the inspector connected to your local server
The Reddit MCP server works perfectly with the MCP Inspector for:
- π OAuth Authentication: Complete OAuth 2.1 flow with PKCE support
- π οΈ Tools: All Reddit interaction tools (search, get posts, notifications, etc.)
- π Prompts: Dynamic prompt generation for content creation
- π€ Sampling: AI-assisted content generation with human-in-the-loop approval
- π‘ Notifications: Real-time progress updates during operations
- β Structured Data: Full JSON Schema validation for inputs/outputs
The inspector provides:
- Interactive tool testing with parameter validation
- OAuth flow visualization and debugging
- Sampling request/response inspection
- Real-time notification monitoring
- Session management visibility
Important: To run tests that interact with Reddit, you need to complete the OAuth flow first:
-
Start the server and open MCP Inspector:
# Build and start the server npm run build node build/index.js # In another terminal, open the MCP Inspector npx @modelcontextprotocol/inspector build/index.js
-
Complete OAuth Authentication:
- The Inspector will prompt you to authenticate
- Follow the OAuth flow to authorize with Reddit
- After successful authentication, the server stores tokens
-
Save OAuth Tokens for Testing:
- Once authenticated via Inspector, copy the generated tokens
- Add them to your
.env
file for persistent testing:
# Add these to your .env after completing OAuth REDDIT_ACCESS_TOKEN=your_access_token REDDIT_REFRESH_TOKEN=your_refresh_token
# Run all tests (requires OAuth tokens in .env)
npm run test
# Run end-to-end tests
npm run e2e
# Build and run with Docker
npm run docker
# Run the server with npx in Docker
docker run --rm -it \
-p 3000:3000 \
-e REDDIT_CLIENT_ID=your_id \
-e REDDIT_CLIENT_SECRET=your_secret \
-e JWT_SECRET=your_jwt_secret \
node:18-alpine \
npx @systemprompt/mcp-server
# Test OAuth flow manually
curl -X POST http://localhost:3000/mcp/v1/initialize \
-H "Content-Type: application/json" \
-d '{"protocolVersion": "2024-11-05", "capabilities": {}}'
# The response will include auth details if tokens are needed
# Build and run with docker-compose (recommended)
npm run docker:build-and-run
# Build image
docker build -t systemprompt-mcp-reddit .
# Run with environment variables
docker run -p 3001:3001 \
-e REDDIT_CLIENT_ID=your_id \
-e REDDIT_CLIENT_SECRET=your_secret \
-e JWT_SECRET=your_jwt_secret \
systemprompt-mcp-reddit
Create a .env
file in the project root with the following variables:
# Required - Reddit OAuth Application Credentials
REDDIT_CLIENT_ID=your_reddit_client_id
REDDIT_CLIENT_SECRET=your_reddit_client_secret
# Optional - Server Configuration
MCP_PORT=3001 # Port for the MCP server (default: 3001)
JWT_SECRET=your_jwt_secret # Secret for JWT signing (default: auto-generated)
DEBUG=true # Enable debug logging (default: false)
Important: The docker:build-and-run
command requires these environment variables to be set either in a .env
file or exported in your shell. Without proper Reddit credentials, the OAuth flow will not work.
systemprompt-mcp-reddit/
βββ src/
β βββ index.ts # Main entry point
β βββ server.ts # HTTP server setup
β βββ server/ # Server infrastructure
β β βββ mcp.ts # MCP protocol handler with session management
β β βββ oauth.ts # OAuth 2.1 implementation
β β βββ middleware.ts # Express middleware (rate limiting, auth)
β β βββ auth-store.ts # Authentication storage
β β βββ config.ts # Server configuration
β βββ handlers/ # Request handlers
β β βββ tool-handlers.ts # Tool execution and validation
β β βββ prompt-handlers.ts # Prompt processing
β β βββ resource-handlers.ts # Resource management
β β βββ sampling.ts # AI sampling implementation
β β βββ notifications.ts # Real-time notifications
β β βββ callbacks/ # Sampling callback handlers
β β βββ tools/ # Individual tool implementations
β βββ services/ # Business logic
β β βββ reddit/ # Reddit API integration
β βββ constants/ # Configuration and definitions
β β βββ tools.ts # Tool definitions
β β βββ resources.ts # Resource definitions
β β βββ sampling/ # Sampling prompt templates
β β βββ server/ # Server configuration constants
β β βββ tool/ # Individual tool constants
β βββ types/ # TypeScript definitions
β β βββ reddit.ts # Reddit-specific types
β β βββ config.ts # Configuration types
β β βββ sampling.ts # Sampling types
β β βββ request-context.ts # Request context types
β βββ utils/ # Helper functions
β βββ logger.ts # Logging utilities
β βββ reddit-transformers.ts # Reddit data transformers
β βββ validation.ts # Validation utilities
βββ scripts/ # Development and testing scripts
βββ docker-compose.yml # Docker configuration
βββ tsconfig.json # TypeScript configuration
βββ package.json # Project configuration
- src/index.ts: Application entry point
- src/server.ts: HTTP server setup and Express configuration
- src/server/mcp.ts: MCP protocol implementation with session management
- src/server/oauth.ts: Complete OAuth 2.1 flow
- src/handlers/tool-handlers.ts: Tool execution with Zod validation
- src/handlers/sampling.ts: AI sampling implementation
- src/services/reddit/reddit-service.ts: Reddit API integration
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Submit a pull request
- Use TypeScript for all code
- Follow the existing patterns
- Add JSDoc comments for public APIs
- Include tests for new features
- Interactive Implementation Guide: Live testing and tutorial
- MCP Specification: Official MCP documentation
- systemprompt.io Documentation: Platform documentation
This project is licensed under the MIT License - see the LICENSE file for details.
- Anthropic for the MCP specification
- Reddit for their comprehensive API
- The MCP community for feedback and contributions
Built with β€οΈ by the systemprompt.io team