
系统提示
STDIO展示OAuth和Reddit集成的MCP服务器
展示OAuth和Reddit集成的MCP服务器
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:
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:
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:
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:
Run the server instantly with Docker - no installation required:
Create a Reddit app at reddit.com/prefs/apps
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
http://localhost:3000
# 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
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 interfacesThis 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)
Authorization Request (src/server/oauth.ts)
Reddit OAuth Callback (src/server/oauth.ts)
Token Exchange (src/server/oauth.ts)
Authenticated Requests (src/server/middleware.ts)
search_reddit
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 }
get_post
Fetch a specific post with comments (src/handlers/tools/get-post.ts)
{ "id": "post_id_here" // Reddit post ID }
get_channel
Get subreddit posts (src/handlers/tools/get-channel.ts)
{ "subreddit": "programming", "sort": "hot" // "hot", "new", or "controversial" }
get_notifications
Fetch user notifications and messages (src/handlers/tools/get-notifications.ts)
{ "filter": "unread", // "all", "unread", "messages", "comments", "mentions" "limit": 25, "markRead": false }
get_comment
Retrieve a specific comment (src/handlers/tools/get-comment.ts)
{ "id": "comment_id_here", "includeThread": true // Include full comment thread }
elicitation_example
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 }
sampling_example
Demonstrates AI-assisted content generation (src/handlers/tools/sampling-example.ts)
{ "prompt": "Generate a code example", "maxTokens": 1000, "temperature": 0.7 }
structured_data_example
Demonstrates structured data handling (src/handlers/tools/structured-data-example.ts)
{ "format": "json", // "json", "table", "markdown" "data": { "key": "value" } }
validation_example
Demonstrates input validation (src/handlers/tools/validation-example.ts)
{ "test_string": "example", "test_number": 42, "test_enum": "option1" }
mcp_logging
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: {} };
# 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:
The Reddit MCP server works perfectly with the MCP Inspector for:
The inspector provides:
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:
Save OAuth Tokens for Testing:
.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
We welcome contributions! Please see our Contributing Guide for details.
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ by the systemprompt.io team