# Directory Structure ``` ├── .github │ └── workflows │ └── node.js.yml ├── .gitignore ├── Dockerfile ├── examples │ └── deep-research.md ├── LICENSE ├── memory-bank │ ├── activeContext.md │ ├── productContext.md │ ├── progress.md │ ├── systemPatterns.md │ └── techContext.md ├── package-lock.json ├── package.json ├── README.md ├── smithery.yaml ├── src │ └── index.ts └── tsconfig.json ``` # Files -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` node_modules/ build/ *.log .env* ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown # Perplexity MCP Server An intelligent research assistant powered by Perplexity's specialized AI models. Features automatic query complexity detection to route requests to the most appropriate model for optimal results. Unlike the Official server, it has search capabilities FOR EVERY TASK, essentially ## Tools **Quick Note: The Deep Research tool is going to timeout with some tools like cline, but not with others like cursor due to implementation differences, but the reason tool makes up for it.** ### 1. Search (Sonar Pro) Quick search for simple queries and basic information lookup. Best for straightforward questions that need concise, direct answers. ```javascript const result = await use_mcp_tool({ server_name: "perplexity", tool_name: "search", arguments: { query: "What is the capital of France?", force_model: false // Optional: force using this model even if query seems complex } }); ``` ### 2. Reason (Sonar Reasoning Pro) Handles complex, multi-step tasks requiring detailed analysis. Perfect for explanations, comparisons, and problem-solving. ```javascript const result = await use_mcp_tool({ server_name: "perplexity", tool_name: "reason", arguments: { query: "Compare and contrast REST and GraphQL APIs, explaining their pros and cons", force_model: false // Optional: force using this model even if query seems simple } }); ``` ### 3. Deep Research (Sonar Deep Research) Conducts comprehensive research and generates detailed reports. Ideal for in-depth analysis of complex topics. ```javascript const result = await use_mcp_tool({ server_name: "perplexity", tool_name: "deep_research", arguments: { query: "The impact of quantum computing on cryptography", focus_areas: [ "Post-quantum cryptographic algorithms", "Timeline for quantum threats", "Practical mitigation strategies" ], force_model: false // Optional: force using this model even if query seems simple } }); ``` ## Intelligent Model Selection The server automatically analyzes query complexity to route requests to the most appropriate model: 1. **Simple Queries** → Sonar Pro - Basic information lookup - Straightforward questions - Quick facts 2. **Complex Queries** → Sonar Reasoning Pro - How/why questions - Comparisons - Step-by-step explanations - Problem-solving tasks 3. **Research Queries** → Sonar Deep Research - In-depth analysis - Comprehensive research - Detailed investigations - Multi-faceted topics You can override the automatic selection using `force_model: true` in any tool's arguments. ## Setup 1. **Prerequisites** - Node.js (from [nodejs.org](https://nodejs.org)) - Perplexity API key (from [perplexity.ai/settings/api](https://www.perplexity.ai/settings/api)) - clone the repo somewhere 2. **Configure MCP Settings** Add to your MCP settings file (location varies by platform): ```json { "mcpServers": { "perplexity": { "command": "node", "args": ["/path/to/perplexity-server/build/index.js"], "env": { "PERPLEXITY_API_KEY": "YOUR_API_KEY_HERE" }, "disabled": false, "autoApprove": [] } } } ``` Or use NPX to not have to install it locally (recommended for macos): ```json { "mcpServers": { "perplexity": { "command": "npx", "args": [ "-y", "perplexity-mcp" ], "env": { "PERPLEXITY_API_KEY": "your_api_key" } } } } ``` ## Star History [](https://www.star-history.com/#DaInfernalCoder/perplexity-mcp&Timeline) ``` -------------------------------------------------------------------------------- /memory-bank/activeContext.md: -------------------------------------------------------------------------------- ```markdown # Recent Changes - Removed unused better-sqlite3 import from src/index.ts that was causing build errors - Successfully built the project after removing the dependency # Current Status - Build is now working correctly - Project is ready for further development ``` -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "target": "ES2022", "module": "Node16", "moduleResolution": "Node16", "outDir": "./build", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules"] } ``` -------------------------------------------------------------------------------- /smithery.yaml: -------------------------------------------------------------------------------- ```yaml # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml startCommand: type: stdio configSchema: # JSON Schema defining the configuration options for the MCP. type: object required: - perplexityApiKey properties: perplexityApiKey: type: string description: The API key for the Perplexity API. commandFunction: # A function that produces the CLI command to start the MCP on stdio. |- (config) => ({ command: 'node', args: ['build/index.js'], env: { PERPLEXITY_API_KEY: config.perplexityApiKey } }) ``` -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- ```yaml # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs name: Node.js CI on: push: branches: [ "main" ] pull_request: branches: [ "main" ] jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: [18.x, 20.x, 22.x] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - run: npm run build --if-present - run: npm test ``` -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- ```dockerfile # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile # Use Node.js LTS version as the base image FROM node:18-alpine AS builder # Set the working directory WORKDIR /app # Copy package.json and package-lock.json to the working directory COPY package.json package-lock.json ./ # Install dependencies RUN npm install --ignore-scripts # Copy the rest of the application code to the working directory COPY . . # Build the TypeScript files RUN npm run build # Use a clean Node.js image for the production environment FROM node:18-alpine AS release # Set the working directory WORKDIR /app # Copy built files and node_modules from the builder stage COPY --from=builder /app/build ./build COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/package.json ./ # Set environment variables (replace YOUR_API_KEY_HERE with the actual key) ENV PERPLEXITY_API_KEY=YOUR_API_KEY_HERE # Expose the port the app runs on EXPOSE 3000 # Command to run the application ENTRYPOINT ["node", "build/index.js"] ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- ```json { "name": "perplexity-mcp", "version": "0.2.0", "description": "MCP server providing intelligent search, reasoning, and research capabilities powered by Perplexity's specialized AI models", "type": "module", "bin": "./build/index.js", "files": [ "build", "README.md", "LICENSE" ], "scripts": { "build": "tsc && chmod +x build/index.js", "watch": "tsc --watch", "start": "node build/index.js", "inspector": "npx @modelcontextprotocol/inspector build/index.js", "test": "tsc --noEmit", "prepublishOnly": "npm run build" }, "dependencies": { "@modelcontextprotocol/sdk": "0.6.0", "axios": "^1.7.9" }, "devDependencies": { "@types/node": "^20.11.24", "typescript": "^5.3.3" }, "keywords": [ "mcp", "perplexity", "ai", "search", "reasoning", "research", "sonar-pro", "sonar-reasoning-pro", "sonar-deep-research", "model-context-protocol" ], "author": "MCP Contributors", "license": "MIT", "repository": { "type": "git", "url": "https://github.com/DaInfernalCoder/researcher-mcp" }, "engines": { "node": ">=18.0.0" } } ``` -------------------------------------------------------------------------------- /memory-bank/progress.md: -------------------------------------------------------------------------------- ```markdown # Progress ## What Works - Server initialization and configuration - MCP protocol implementation - Intelligent query routing system - Three specialized tools implemented: - search (Sonar Pro) - reason (Sonar Reasoning Pro) - deep_research (Sonar Deep Research) - Automatic model selection based on query complexity - Manual model override with force_model flag - Build process with TypeScript - Direct Node.js execution ## Recent Updates 1. **Core Implementation** - [x] Removed chat history and SQLite - [x] Implemented query complexity detection - [x] Added specialized tool handlers - [x] Updated server version to 0.2.0 2. **Documentation** - [x] Updated README with new tools - [x] Added model selection documentation - [x] Updated setup instructions - [x] Added usage examples 3. **Memory Bank** - [x] Updated productContext.md - [x] Updated systemPatterns.md - [x] Updated techContext.md - [x] Updated activeContext.md - [x] Updated progress.md ## What's Next 1. **Testing** - [ ] Test query complexity detection - [ ] Verify model selection logic - [ ] Test each specialized tool - [ ] Validate force_model override 2. **Potential Improvements** - [ ] Expand complexity detection patterns - [ ] Add more specialized prompts per model - [ ] Enhance error messages - [ ] Add query preprocessing ## Current Status - Streamlined architecture with three specialized tools - Intelligent query routing system implemented - All documentation updated - Ready for testing and validation ``` -------------------------------------------------------------------------------- /memory-bank/techContext.md: -------------------------------------------------------------------------------- ```markdown # Technical Context ## Technologies Used ### Core Technologies - **Node.js**: Runtime environment - **TypeScript**: Type-safe development - **MCP SDK**: Server implementation - **Perplexity API**: AI model integration ### Dependencies - **@modelcontextprotocol/sdk (0.6.0)**: MCP protocol implementation - **axios (^1.7.9)**: API communication ### Development Dependencies - **@types/node (^20.11.24)**: Node.js type definitions - **typescript (^5.3.3)**: TypeScript compiler ## AI Models 1. **Sonar Pro** - Quick information retrieval - Simple query processing - Direct answers 2. **Sonar Reasoning Pro** - Complex analysis - Multi-step reasoning - Detailed explanations 3. **Sonar Deep Research** - Comprehensive research - In-depth analysis - Structured reports ## Development Setup 1. **Build Process** - TypeScript compilation - Watch mode for development - Direct Node.js execution 2. **Testing** - Type checking - MCP Inspector integration - Manual tool testing 3. **Environment Variables** - PERPLEXITY_API_KEY (required) ## Technical Constraints 1. **API Requirements** - Valid Perplexity API key - Rate limits and quotas - API availability 2. **Runtime Requirements** - Node.js environment - Local dependencies - MCP protocol support 3. **Query Processing** - Pattern-based analysis - Model selection logic - Response formatting ## Local Setup 1. **Installation** - Clone repository - Install dependencies - Build TypeScript - Configure API key 2. **Configuration** - Environment setup - MCP settings - Model selection rules 3. **Usage** - Direct Node.js execution - Tool selection - Query complexity handling ``` -------------------------------------------------------------------------------- /memory-bank/systemPatterns.md: -------------------------------------------------------------------------------- ```markdown # System Patterns ## Architecture The Perplexity Server implements a streamlined MCP architecture focused on intelligent query routing: 1. **Server Initialization** - Creates MCP server instance - Sets up API client with authentication - Registers specialized tool handlers 2. **Query Analysis System** - Pattern-based complexity detection - Intelligent model selection - Override capabilities via force_model flag 3. **Tool Specialization** - search: Quick lookups (Sonar Pro) - reason: Complex analysis (Sonar Reasoning Pro) - deep_research: Comprehensive research (Sonar Deep Research) 4. **API Integration** - Communicates with Perplexity API - Model-specific request handling - Structured response formatting ## Key Technical Decisions 1. **Intelligent Routing** - Pattern-based query analysis - Automatic model selection - Manual override capability - Optimized response quality 2. **Model Specialization** - Sonar Pro: Simple queries - Sonar Reasoning Pro: Complex analysis - Sonar Deep Research: In-depth research 3. **TypeScript Implementation** - Strong typing for tool schemas - Enhanced code reliability - Better developer experience 4. **Direct Execution** - Node.js runtime - Local dependency management - Simple configuration 5. **Error Handling** - Detailed error messages - API error conversion - Graceful shutdown - Query validation ## Communication Patterns 1. **MCP Protocol** - Stdio transport - Structured request/response - Tool schema definitions - Input validation 2. **API Communication** - RESTful endpoints - Model-specific formatting - Bearer authentication - Error handling 3. **Query Processing** - Complexity analysis - Model selection - Response formatting - Context management ``` -------------------------------------------------------------------------------- /memory-bank/productContext.md: -------------------------------------------------------------------------------- ```markdown # Product Context ## Purpose The Perplexity Server is an MCP (Model Context Protocol) server that provides intelligent research and information retrieval through specialized AI models. It automatically analyzes query complexity to route requests to the most appropriate Perplexity AI model, ensuring optimal responses for different types of queries. ## Problems Solved 1. **Query Optimization**: Automatically selects the best AI model based on query complexity 2. **Information Access**: Provides quick answers to simple questions using Sonar Pro 3. **Complex Analysis**: Handles multi-step reasoning and detailed explanations with Sonar Reasoning Pro 4. **Deep Research**: Conducts comprehensive research and analysis using Sonar Deep Research 5. **Efficiency**: Streamlines information retrieval by matching query complexity to model capabilities ## How It Works The server analyzes queries and routes them to three specialized tools: 1. **search (Sonar Pro)** - Quick information lookup - Simple factual queries - Direct, concise answers - Best for straightforward questions 2. **reason (Sonar Reasoning Pro)** - Complex problem-solving - Multi-step analysis - Comparisons and trade-offs - Detailed explanations - Best for how/why questions 3. **deep_research (Sonar Deep Research)** - Comprehensive research - In-depth analysis - Multiple perspectives - Source references - Best for complex topics The server features intelligent query analysis that automatically routes requests to the appropriate model based on complexity patterns, with manual override available through the force_model flag. ## Key Features 1. **Automatic Model Selection** - Pattern-based complexity detection - Intelligent routing to appropriate model - Override capability for manual control 2. **Specialized Response Formats** - Concise answers for simple queries - Structured analysis for complex questions - Comprehensive reports for research topics 3. **Query Analysis** - Keyword and pattern detection - Complexity assessment - Context consideration - Model-specific formatting ``` -------------------------------------------------------------------------------- /examples/deep-research.md: -------------------------------------------------------------------------------- ```markdown # Deep Research Tool The `deep_research` tool allows you to conduct comprehensive, in-depth research on complex topics using Perplexity's sonar-deep-research model. This tool is designed for situations where you need thorough analysis and detailed information beyond what a standard search can provide. ## Example Usage ```javascript const result = await use_mcp_tool({ server_name: "perplexity-ask", tool_name: "deep_research", arguments: { query: "The impact of quantum computing on cryptography", focus_areas: [ "Post-quantum cryptographic algorithms", "Timeline for quantum threats to current encryption", "Practical mitigation strategies for organizations" ] } }); console.log(result); ``` ## Parameters - `query` (required): The research query or topic to investigate in depth - `focus_areas` (optional): An array of specific aspects or areas to focus on during research - `output_format` (optional): Format of the response (text or dropdown), defaults to "text" ## Example Response The response will include a comprehensive analysis with: 1. Background and context 2. Key concepts and definitions 3. Current state of knowledge 4. Different perspectives and approaches 5. Recent developments and breakthroughs 6. Practical applications or implications 7. Challenges and limitations 8. Future directions 9. Expert opinions and consensus views 10. References to authoritative sources ## When to Use Use the `deep_research` tool when: - You need comprehensive information on complex topics - Standard search results aren't providing enough depth - You want analysis that considers multiple perspectives - You need information on cutting-edge or rapidly evolving fields - You're looking for expert consensus and authoritative sources ## Comparison with Search Tool While the `search` tool is great for quick answers and general information, the `deep_research` tool provides: - Greater depth and breadth of analysis - More comprehensive coverage of different perspectives - Better handling of complex, nuanced topics - More thorough citation of sources and expert opinions - Ability to focus on specific aspects of a broader topic ``` -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- ```typescript #!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, McpError, ErrorCode, } from "@modelcontextprotocol/sdk/types.js"; import axios from "axios"; import { existsSync, mkdirSync } from "fs"; import { dirname, join } from "path"; import { homedir } from "os"; const PERPLEXITY_API_KEY = process.env.PERPLEXITY_API_KEY; if (!PERPLEXITY_API_KEY) { throw new Error("PERPLEXITY_API_KEY environment variable is required"); } class PerplexityServer { private server: Server; private axiosInstance; constructor() { this.server = new Server( { name: "perplexity-server", version: "0.2.0", }, { capabilities: { tools: {}, }, } ); this.axiosInstance = axios.create({ baseURL: "https://api.perplexity.ai", headers: { "Authorization": `Bearer ${PERPLEXITY_API_KEY}`, "Content-Type": "application/json", }, }); this.setupToolHandlers(); // Error handling this.server.onerror = (error) => console.error("[MCP Error]", error); process.on("SIGINT", async () => { await this.server.close(); process.exit(0); }); } /** * Determines the complexity of a query to choose the appropriate model */ private determineQueryComplexity(query: string): "simple" | "complex" | "research" { // Check for research indicators const researchIndicators = [ "analyze", "research", "investigate", "study", "examine", "explore", "comprehensive", "detailed", "in-depth", "thorough", "compare and contrast", "evaluate", "assess" ]; // Check for complex reasoning indicators const complexIndicators = [ "how", "why", "what if", "explain", "solve", "steps to", "difference between", "compare", "which is better", "pros and cons", "advantages", "disadvantages" ]; const query_lower = query.toLowerCase(); // Check for research patterns if (researchIndicators.some(indicator => query_lower.includes(indicator))) { return "research"; } // Check for complex patterns if (complexIndicators.some(indicator => query_lower.includes(indicator))) { return "complex"; } // Default to simple if no complex/research patterns found return "simple"; } private setupToolHandlers() { this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: "search", description: "Quick search for simple queries using Perplexity's Sonar Pro model. Best for straightforward questions and basic information lookup.", inputSchema: { type: "object", properties: { query: { type: "string", description: "The search query or question" }, force_model: { type: "boolean", description: "Optional: Force using this model even if query seems complex", default: false } }, required: ["query"] } }, { name: "reason", description: "Handles complex, multi-step tasks using Perplexity's Sonar Reasoning Pro model. Best for explanations, comparisons, and problem-solving.", inputSchema: { type: "object", properties: { query: { type: "string", description: "The complex query or task to reason about" }, force_model: { type: "boolean", description: "Optional: Force using this model even if query seems simple/research-oriented", default: false } }, required: ["query"] } }, { name: "deep_research", description: "Conducts in-depth analysis and generates detailed reports using Perplexity's Sonar Deep Research model. Best for comprehensive research topics.", inputSchema: { type: "object", properties: { query: { type: "string", description: "The research topic or question to investigate in depth" }, focus_areas: { type: "array", items: { type: "string" }, description: "Optional: Specific aspects or areas to focus on" }, force_model: { type: "boolean", description: "Optional: Force using this model even if query seems simple", default: false } }, required: ["query"] } } ] })); this.server.setRequestHandler(CallToolRequestSchema, async (request) => { try { const { query, force_model = false } = request.params.arguments as { query: string; force_model?: boolean; }; // Determine which model to use based on query complexity let selectedTool = request.params.name; if (!force_model && selectedTool === "search") { const complexity = this.determineQueryComplexity(query); if (complexity === "complex") { selectedTool = "reason"; } else if (complexity === "research") { selectedTool = "deep_research"; } } let model: string; let prompt: string; switch (selectedTool) { case "search": { model = "sonar-pro"; prompt = `Provide a clear, concise answer to: ${query}`; break; } case "reason": { model = "sonar-reasoning-pro"; prompt = `Provide a detailed explanation and analysis for: ${query}. Include: 1. Step-by-step reasoning 2. Key considerations 3. Relevant examples 4. Practical implications 5. Potential alternatives`; break; } case "deep_research": { model = "sonar-deep-research"; const { focus_areas = [] } = request.params.arguments as { focus_areas?: string[] }; prompt = `Conduct comprehensive research on: ${query}`; if (focus_areas.length > 0) { prompt += `\n\nFocus areas:\n${focus_areas.map((area, i) => `${i + 1}. ${area}`).join('\n')}`; } prompt += `\n\nProvide a detailed analysis including: 1. Background and context 2. Key concepts and definitions 3. Current state of knowledge 4. Different perspectives 5. Recent developments 6. Practical applications 7. Challenges and limitations 8. Future directions 9. Expert opinions 10. References to sources`; break; } default: throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}` ); } const response = await this.axiosInstance.post("/chat/completions", { model, messages: [{ role: "user", content: prompt }], }); // response.data can have a string[] .citations // these are referred to in the return text as numbered citations e.g. [1] const sourcesText = response.data.citations ? `\n\n## Sources\nPlease keep the numbered citations inline.\n${response.data.citations .map((c: string, i: number) => `${i + 1}: ${c}`) .join("\n")}` : ""; return { content: [{ type: "text", text: response.data.choices[0].message.content + sourcesText, }] }; } catch (error) { if (axios.isAxiosError(error)) { throw new McpError( ErrorCode.InternalError, `Perplexity API error: ${error.response?.data?.error?.message || error.message}` ); } throw error; } }); } async run() { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error("Perplexity MCP server running on stdio"); } } const server = new PerplexityServer(); server.run().catch(console.error); ```